Skip to content

Commit 4a73548

Browse files
authored
feat: Support Turbo Modules (#1101)
1 parent e604173 commit 4a73548

19 files changed

Lines changed: 420 additions & 307 deletions

File tree

A0Auth0.podspec

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
require 'json'
22

33
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4+
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
45

56
Pod::Spec.new do |s|
67
s.name = 'A0Auth0'
@@ -20,4 +21,16 @@ Pod::Spec.new do |s|
2021
s.dependency 'Auth0', '2.7.2'
2122
s.dependency 'JWTDecode', '3.1.0'
2223
s.dependency 'SimpleKeychain', '1.1.0'
24+
25+
s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1"
26+
s.pod_target_xcconfig = {
27+
"HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"",
28+
"OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1",
29+
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17"
30+
}
31+
s.dependency "React-Codegen"
32+
s.dependency "RCT-Folly"
33+
s.dependency "RCTRequired"
34+
s.dependency "RCTTypeSafety"
35+
s.dependency "ReactCommon/turbomodule/core"
2336
end

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ We're excited to announce the release of react-native-auth0 `v4.0.0`! Please not
2828

2929
### Requirements
3030

31-
This SDK targets apps that are using React Native SDK version `0.65.0` and up. If you're using an older React Native version, see the compatibility matrix below.
31+
This SDK targets apps that are using React Native SDK version `0.76.0` and up. If you're using an older React Native version, see the compatibility matrix below.
3232

3333
### Platform compatibility
3434

android/build.gradle

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ buildscript {
1616

1717
apply plugin: 'com.android.library'
1818
apply plugin: 'maven-publish'
19+
apply plugin: "com.facebook.react"
1920

2021
// Matches values in recent template from React Native 0.62
2122
// https://github.com/facebook/react-native/blob/0.62-stable/template/android/build.gradle#L5-L8
@@ -35,13 +36,25 @@ android {
3536
versionCode 1
3637
versionName "1.0"
3738
}
39+
buildFeatures {
40+
buildConfig true
41+
}
3842
lintOptions {
3943
abortOnError false
4044
}
4145
compileOptions {
4246
sourceCompatibility JavaVersion.VERSION_1_8
4347
targetCompatibility JavaVersion.VERSION_1_8
4448
}
49+
50+
sourceSets {
51+
main {
52+
java.srcDirs += [
53+
"generated/java",
54+
"generated/jni"
55+
]
56+
}
57+
}
4558
}
4659

4760
repositories {
@@ -129,3 +142,9 @@ afterEvaluate { project ->
129142
}
130143
}
131144
}
145+
146+
react {
147+
jsRootDir = file("../src/")
148+
libraryName = "A0Auth0"
149+
codegenJavaPackageName = "com.auth0.react"
150+
}

android/src/main/java/com/auth0/react/A0Auth0Module.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ public A0Auth0Module(ReactApplicationContext reactContext) {
8484
this.reactContext.addActivityEventListener(this);
8585
}
8686

87+
@ReactMethod
88+
public String getBundleIdentifier() {
89+
return reactContext.getApplicationInfo().packageName;
90+
}
91+
8792
@ReactMethod
8893
public void initializeAuth0WithConfiguration(String clientId, String domain, ReadableMap localAuthenticationOptions, Promise promise) {
8994
this.auth0 = Auth0.getInstance(clientId, domain);

ios/A0Auth0.m renamed to ios/A0Auth0.mm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ - (dispatch_queue_t)methodQueue
1919

2020
RCT_EXPORT_MODULE();
2121

22+
RCT_EXPORT_METHOD(getBundleIdentifier:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
23+
resolve([[NSBundle mainBundle] bundleIdentifier]);
24+
}
25+
2226
RCT_EXPORT_METHOD(hasValidAuth0InstanceWithConfiguration:(NSString *)clientId domain:(NSString *)domain resolver:(RCTPromiseResolveBlock)resolve
2327
rejecter:(RCTPromiseRejectBlock)reject) {
2428
BOOL valid = [self checkHasValidNativeBridgeInstance:clientId domain:domain];

ios/A0Auth0.xcodeproj/project.pbxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
/* Begin PBXBuildFile section */
1010
2979802E2A3B572E0087BE80 /* NativeBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2979802D2A3B572E0087BE80 /* NativeBridge.swift */; };
11-
B3E7B58A1CC2AC0600A0062D /* A0Auth0.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* A0Auth0.m */; };
11+
B3E7B58A1CC2AC0600A0062D /* A0Auth0.mm in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* A0Auth0.mm */; };
1212
/* End PBXBuildFile section */
1313

1414
/* Begin PBXCopyFilesBuildPhase section */
@@ -28,7 +28,7 @@
2828
2979802D2A3B572E0087BE80 /* NativeBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NativeBridge.swift; sourceTree = "<group>"; };
2929
A7107F0228A30FF7003A6450 /* A0Auth0-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "A0Auth0-Bridging-Header.h"; sourceTree = "<group>"; };
3030
B3E7B5881CC2AC0600A0062D /* A0Auth0.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = A0Auth0.h; sourceTree = "<group>"; };
31-
B3E7B5891CC2AC0600A0062D /* A0Auth0.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = A0Auth0.m; sourceTree = "<group>"; };
31+
B3E7B5891CC2AC0600A0062D /* A0Auth0.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = A0Auth0.mm; sourceTree = "<group>"; };
3232
/* End PBXFileReference section */
3333

3434
/* Begin PBXFrameworksBuildPhase section */
@@ -55,7 +55,7 @@
5555
children = (
5656
2979802D2A3B572E0087BE80 /* NativeBridge.swift */,
5757
B3E7B5881CC2AC0600A0062D /* A0Auth0.h */,
58-
B3E7B5891CC2AC0600A0062D /* A0Auth0.m */,
58+
B3E7B5891CC2AC0600A0062D /* A0Auth0.mm */,
5959
134814211AA4EA7D00B7C361 /* Products */,
6060
A7107F0228A30FF7003A6450 /* A0Auth0-Bridging-Header.h */,
6161
);
@@ -119,7 +119,7 @@
119119
isa = PBXSourcesBuildPhase;
120120
buildActionMask = 2147483647;
121121
files = (
122-
B3E7B58A1CC2AC0600A0062D /* A0Auth0.m in Sources */,
122+
B3E7B58A1CC2AC0600A0062D /* A0Auth0.mm in Sources */,
123123
2979802E2A3B572E0087BE80 /* NativeBridge.swift in Sources */,
124124
);
125125
runOnlyForDeploymentPostprocessing = 0;

package.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,5 +236,13 @@
236236
"hooks": {
237237
"pre-commit": "pretty-quick --staged"
238238
}
239+
},
240+
"codegenConfig": {
241+
"name": "RNAuth0Spec",
242+
"type": "modules",
243+
"jsSrcsDir": "src",
244+
"android": {
245+
"javaPackageName": "com.auth0.react"
246+
}
239247
}
240248
}

src/credentials-manager/__tests__/credentials-manager.spec.js

Lines changed: 32 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,37 @@
11
import CredentialsManager from '../index';
22
import CredentialsManagerError from '../credentialsManagerError';
3-
import { Platform } from 'react-native';
3+
import A0Auth0 from '../../specs/NativeA0Auth0';
4+
5+
// Mock the native module
6+
jest.mock('../../specs/NativeA0Auth0');
47

58
describe('credentials manager tests', () => {
69
const credentialsManager = new CredentialsManager(
710
'https://auth0.com',
811
'abc123'
912
);
1013

11-
credentialsManager.Auth0Module.hasValidAuth0InstanceWithConfiguration = () =>
12-
Promise.resolve(true);
13-
credentialsManager.Auth0Module.saveCredentials = () => {};
14-
credentialsManager.Auth0Module.getCredentials = () => {};
15-
credentialsManager.Auth0Module.hasValidCredentials = () => {};
16-
credentialsManager.Auth0Module.clearCredentials = () => {};
17-
credentialsManager.Auth0Module.enableLocalAuthentication = () => {};
18-
1914
const validToken = {
2015
idToken: '1234',
2116
accessToken: '1234',
2217
tokenType: 'Bearer',
2318
expiresAt: 1691603391,
2419
};
2520

21+
beforeEach(() => {
22+
// Reset all mocks before each test
23+
jest.clearAllMocks();
24+
25+
// Set default implementation for native module functions
26+
A0Auth0.hasValidAuth0InstanceWithConfiguration = jest.fn(() =>
27+
Promise.resolve(true)
28+
);
29+
A0Auth0.saveCredentials = jest.fn(() => Promise.resolve(true));
30+
A0Auth0.getCredentials = jest.fn(() => Promise.resolve());
31+
A0Auth0.hasValidCredentials = jest.fn(() => Promise.resolve(false));
32+
A0Auth0.clearCredentials = jest.fn(() => Promise.resolve(true));
33+
});
34+
2635
describe('test saving credentials', () => {
2736
it('throws when access token is empty', async () => {
2837
const testToken = Object.assign({}, validToken);
@@ -65,108 +74,75 @@ describe('credentials manager tests', () => {
6574
});
6675

6776
it('proper error is thrown for exception', async () => {
68-
const newNativeModule = jest
69-
.spyOn(
70-
credentialsManager.Auth0Module,
71-
'hasValidAuth0InstanceWithConfiguration'
72-
)
73-
.mockImplementation(() => {
74-
throw Error('123123');
75-
});
77+
A0Auth0.hasValidAuth0InstanceWithConfiguration = jest.fn(() => {
78+
throw Error('123123');
79+
});
7680
await expect(
7781
credentialsManager.saveCredentials(validToken)
7882
).rejects.toThrow();
79-
newNativeModule.mockRestore();
8083
});
8184

8285
it('succeeds for proper token', async () => {
83-
const newNativeModule = jest
84-
.spyOn(credentialsManager.Auth0Module, 'saveCredentials')
85-
.mockImplementation(() => Promise.resolve(true));
86+
A0Auth0.saveCredentials = jest.fn(() => Promise.resolve(true));
8687
await expect(
8788
credentialsManager.saveCredentials(validToken)
8889
).resolves.toEqual(true);
89-
newNativeModule.mockRestore();
9090
});
9191
});
9292

9393
describe('test getting credentials', () => {
9494
it('proper error is thrown for exception', async () => {
95-
const newNativeModule = jest
96-
.spyOn(credentialsManager.Auth0Module, 'getCredentials')
97-
.mockImplementation(() => {
98-
throw Error('123123');
99-
});
95+
A0Auth0.getCredentials = jest.fn(() => {
96+
throw Error('123123');
97+
});
10098
await expect(credentialsManager.getCredentials()).rejects.toThrow();
101-
newNativeModule.mockRestore();
10299
});
103100

104101
it('succeedsfully returns credentials', async () => {
105-
const newNativeModule = jest
106-
.spyOn(credentialsManager.Auth0Module, 'getCredentials')
107-
.mockImplementation(() => Promise.resolve(validToken));
102+
A0Auth0.getCredentials = jest.fn(() => Promise.resolve(validToken));
108103
await expect(credentialsManager.getCredentials()).resolves.toEqual(
109104
validToken
110105
);
111-
newNativeModule.mockRestore();
112106
});
113107

114108
it('passes along the forceRefresh parameter', async () => {
115-
const newNativeModule = jest
116-
.spyOn(credentialsManager.Auth0Module, 'getCredentials')
117-
.mockImplementation(() => Promise.resolve(validToken));
109+
A0Auth0.getCredentials = jest.fn(() => Promise.resolve(validToken));
118110

119111
await credentialsManager.getCredentials(null, 0, {}, true);
120112

121-
expect(
122-
credentialsManager.Auth0Module.getCredentials
123-
).toHaveBeenCalledWith(null, 0, {}, true);
124-
125-
newNativeModule.mockRestore();
113+
expect(A0Auth0.getCredentials).toHaveBeenCalledWith(null, 0, {}, true);
126114
});
127115
});
128116

129117
describe('test hasValidCredentials', () => {
130118
it('returns false', async () => {
131-
const newNativeModule = jest
132-
.spyOn(credentialsManager.Auth0Module, 'hasValidCredentials')
133-
.mockImplementation(() => Promise.resolve(true));
119+
A0Auth0.hasValidCredentials = jest.fn(() => Promise.resolve(true));
134120
await expect(credentialsManager.hasValidCredentials()).resolves.toEqual(
135121
true
136122
);
137-
newNativeModule.mockRestore();
138123
});
139124

140125
it('returns true', async () => {
141-
const newNativeModule = jest
142-
.spyOn(credentialsManager.Auth0Module, 'hasValidCredentials')
143-
.mockImplementation(() => Promise.resolve(true));
126+
A0Auth0.hasValidCredentials = jest.fn(() => Promise.resolve(true));
144127
await expect(credentialsManager.hasValidCredentials()).resolves.toEqual(
145128
true
146129
);
147-
newNativeModule.mockRestore();
148130
});
149131
});
150132

151133
describe('test clearing credentials', () => {
152134
it('returns false', async () => {
153-
const newNativeModule = jest
154-
.spyOn(credentialsManager.Auth0Module, 'clearCredentials')
155-
.mockImplementation(() => Promise.resolve(true));
135+
A0Auth0.clearCredentials = jest.fn(() => Promise.resolve(true));
156136
await expect(credentialsManager.clearCredentials()).resolves.toEqual(
157137
true
158138
);
159-
newNativeModule.mockRestore();
160139
});
161140

162141
it('returns true', async () => {
163-
const newNativeModule = jest
164-
.spyOn(credentialsManager.Auth0Module, 'clearCredentials')
165-
.mockImplementation(() => Promise.resolve(true));
142+
A0Auth0.clearCredentials = jest.fn(() => Promise.resolve(true));
166143
await expect(credentialsManager.clearCredentials()).resolves.toEqual(
167144
true
168145
);
169-
newNativeModule.mockRestore();
170146
});
171147
});
172148

0 commit comments

Comments
 (0)