@react-native-firebase/auth 23.5.0 → 23.7.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.
- package/CHANGELOG.md +12 -0
- package/android/build.gradle +3 -5
- package/lib/index.js +59 -7
- package/lib/modular/index.js +7 -7
- package/lib/password-policy/PasswordPolicyMixin.js +66 -0
- package/lib/password-policy/passwordPolicyApi.js +1 -12
- package/lib/version.js +1 -1
- package/package.json +4 -4
- package/plugin/build/ios/openUrlFix.js +4 -0
- package/plugin/src/ios/openUrlFix.ts +4 -0
- package/plugin/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [23.7.0](https://github.com/invertase/react-native-firebase/compare/v23.6.0...v23.7.0) (2025-12-08)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- **auth:** cache password policy per-app in validatePassword ([cc29117](https://github.com/invertase/react-native-firebase/commit/cc291171e076d00dfde1fef9d03242379e567af4))
|
|
11
|
+
|
|
12
|
+
## [23.6.0](https://github.com/invertase/react-native-firebase/compare/v23.5.0...v23.6.0) (2025-12-08)
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
- **auth, ios:** append openURL changes only once in Expo plugin ([#8763](https://github.com/invertase/react-native-firebase/issues/8763)) ([5f74256](https://github.com/invertase/react-native-firebase/commit/5f74256d2b470456206a3655ff6986198d016790))
|
|
17
|
+
|
|
6
18
|
## [23.5.0](https://github.com/invertase/react-native-firebase/compare/v23.4.1...v23.5.0) (2025-10-30)
|
|
7
19
|
|
|
8
20
|
**Note:** Version bump only for package @react-native-firebase/auth
|
package/android/build.gradle
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import com.android.Version
|
|
1
2
|
import io.invertase.gradle.common.PackageJson
|
|
2
3
|
|
|
3
4
|
buildscript {
|
|
@@ -36,11 +37,8 @@ def jsonTargetSdk = appPackageJson['sdkVersions']['android']['targetSdk']
|
|
|
36
37
|
def jsonCompileSdk = appPackageJson['sdkVersions']['android']['compileSdk']
|
|
37
38
|
def coreVersionDetected = appPackageJson['version']
|
|
38
39
|
def coreVersionRequired = packageJson['peerDependencies'][appPackageJson['name']]
|
|
39
|
-
// Only log after build completed so log warning appears at the end
|
|
40
40
|
if (coreVersionDetected != coreVersionRequired) {
|
|
41
|
-
|
|
42
|
-
project.logger.warn("ReactNativeFirebase WARNING: NPM package '${packageJson['name']}' depends on '${appPackageJson['name']}' v${coreVersionRequired} but found v${coreVersionDetected}, this might cause build issues or runtime crashes.")
|
|
43
|
-
}
|
|
41
|
+
project.logger.warn("ReactNativeFirebase WARNING: NPM package '${packageJson['name']}' depends on '${appPackageJson['name']}' v${coreVersionRequired} but found v${coreVersionDetected}, this might cause build issues or runtime crashes.")
|
|
44
42
|
}
|
|
45
43
|
|
|
46
44
|
project.ext {
|
|
@@ -59,7 +57,7 @@ project.ext {
|
|
|
59
57
|
}
|
|
60
58
|
|
|
61
59
|
android {
|
|
62
|
-
def agpVersion =
|
|
60
|
+
def agpVersion = Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')[0].toInteger()
|
|
63
61
|
if (agpVersion >= 7) {
|
|
64
62
|
namespace = 'io.invertase.firebase.auth'
|
|
65
63
|
}
|
package/lib/index.js
CHANGED
|
@@ -51,6 +51,7 @@ import TwitterAuthProvider from './providers/TwitterAuthProvider';
|
|
|
51
51
|
import { TotpSecret } from './TotpSecret';
|
|
52
52
|
import version from './version';
|
|
53
53
|
import fallBackModule from './web/RNFBAuthModule';
|
|
54
|
+
import { PasswordPolicyMixin } from './password-policy/PasswordPolicyMixin';
|
|
54
55
|
|
|
55
56
|
const PhoneAuthState = {
|
|
56
57
|
CODE_SENT: 'sent',
|
|
@@ -103,6 +104,8 @@ class FirebaseAuthModule extends FirebaseModule {
|
|
|
103
104
|
this._authResult = false;
|
|
104
105
|
this._languageCode = this.native.APP_LANGUAGE[this.app._name];
|
|
105
106
|
this._tenantId = null;
|
|
107
|
+
this._projectPasswordPolicy = null;
|
|
108
|
+
this._tenantPasswordPolicies = {};
|
|
106
109
|
|
|
107
110
|
if (!this.languageCode) {
|
|
108
111
|
this._languageCode = this.native.APP_LANGUAGE['[DEFAULT]'];
|
|
@@ -336,15 +339,45 @@ class FirebaseAuthModule extends FirebaseModule {
|
|
|
336
339
|
}
|
|
337
340
|
|
|
338
341
|
createUserWithEmailAndPassword(email, password) {
|
|
339
|
-
return
|
|
340
|
-
.
|
|
341
|
-
|
|
342
|
+
return (
|
|
343
|
+
this.native
|
|
344
|
+
.createUserWithEmailAndPassword(email, password)
|
|
345
|
+
.then(userCredential => this._setUserCredential(userCredential))
|
|
346
|
+
/* istanbul ignore next - native error handling cannot be unit tested */
|
|
347
|
+
.catch(error => {
|
|
348
|
+
if (error.code === 'auth/password-does-not-meet-requirements') {
|
|
349
|
+
return this._recachePasswordPolicy()
|
|
350
|
+
.catch(() => {
|
|
351
|
+
// Silently ignore recache failures - the original error matters more
|
|
352
|
+
})
|
|
353
|
+
.then(() => {
|
|
354
|
+
throw error;
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
throw error;
|
|
358
|
+
})
|
|
359
|
+
);
|
|
342
360
|
}
|
|
343
361
|
|
|
344
362
|
signInWithEmailAndPassword(email, password) {
|
|
345
|
-
return
|
|
346
|
-
.
|
|
347
|
-
|
|
363
|
+
return (
|
|
364
|
+
this.native
|
|
365
|
+
.signInWithEmailAndPassword(email, password)
|
|
366
|
+
.then(userCredential => this._setUserCredential(userCredential))
|
|
367
|
+
/* istanbul ignore next - native error handling cannot be unit tested */
|
|
368
|
+
.catch(error => {
|
|
369
|
+
if (error.code === 'auth/password-does-not-meet-requirements') {
|
|
370
|
+
return this._recachePasswordPolicy()
|
|
371
|
+
.catch(() => {
|
|
372
|
+
// Silently ignore recache failures - the original error matters more
|
|
373
|
+
})
|
|
374
|
+
.then(() => {
|
|
375
|
+
throw error;
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
throw error;
|
|
379
|
+
})
|
|
380
|
+
);
|
|
348
381
|
}
|
|
349
382
|
|
|
350
383
|
signInWithCustomToken(customToken) {
|
|
@@ -382,7 +415,23 @@ class FirebaseAuthModule extends FirebaseModule {
|
|
|
382
415
|
}
|
|
383
416
|
|
|
384
417
|
confirmPasswordReset(code, newPassword) {
|
|
385
|
-
return
|
|
418
|
+
return (
|
|
419
|
+
this.native
|
|
420
|
+
.confirmPasswordReset(code, newPassword)
|
|
421
|
+
/* istanbul ignore next - native error handling cannot be unit tested */
|
|
422
|
+
.catch(error => {
|
|
423
|
+
if (error.code === 'auth/password-does-not-meet-requirements') {
|
|
424
|
+
return this._recachePasswordPolicy()
|
|
425
|
+
.catch(() => {
|
|
426
|
+
// Silently ignore recache failures - the original error matters more
|
|
427
|
+
})
|
|
428
|
+
.then(() => {
|
|
429
|
+
throw error;
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
throw error;
|
|
433
|
+
})
|
|
434
|
+
);
|
|
386
435
|
}
|
|
387
436
|
|
|
388
437
|
applyActionCode(code) {
|
|
@@ -493,6 +542,9 @@ class FirebaseAuthModule extends FirebaseModule {
|
|
|
493
542
|
}
|
|
494
543
|
}
|
|
495
544
|
|
|
545
|
+
// Apply password policy mixin to FirebaseAuthModule
|
|
546
|
+
Object.assign(FirebaseAuthModule.prototype, PasswordPolicyMixin);
|
|
547
|
+
|
|
496
548
|
// import { SDK_VERSION } from '@react-native-firebase/auth';
|
|
497
549
|
export const SDK_VERSION = version;
|
|
498
550
|
|
package/lib/modular/index.js
CHANGED
|
@@ -16,8 +16,6 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import { getApp } from '@react-native-firebase/app';
|
|
19
|
-
import { fetchPasswordPolicy } from '../password-policy/passwordPolicyApi';
|
|
20
|
-
import { PasswordPolicyImpl } from '../password-policy/PasswordPolicyImpl';
|
|
21
19
|
import { MultiFactorUser } from '../multiFactor';
|
|
22
20
|
import { MODULAR_DEPRECATION_ARG } from '@react-native-firebase/app/lib/common';
|
|
23
21
|
|
|
@@ -637,15 +635,17 @@ export function getCustomAuthDomain(auth) {
|
|
|
637
635
|
* @returns {Promise<PasswordValidationStatus>}
|
|
638
636
|
*/
|
|
639
637
|
export async function validatePassword(auth, password) {
|
|
638
|
+
if (!auth || !auth.app) {
|
|
639
|
+
throw new Error(
|
|
640
|
+
"firebase.auth().validatePassword(*) 'auth' must be a valid Auth instance with an 'app' property. Received: undefined",
|
|
641
|
+
);
|
|
642
|
+
}
|
|
643
|
+
|
|
640
644
|
if (password === null || password === undefined) {
|
|
641
645
|
throw new Error(
|
|
642
646
|
"firebase.auth().validatePassword(*) expected 'password' to be a non-null or a defined value.",
|
|
643
647
|
);
|
|
644
648
|
}
|
|
645
|
-
let passwordPolicy = await fetchPasswordPolicy(auth);
|
|
646
|
-
|
|
647
|
-
const passwordPolicyImpl = await new PasswordPolicyImpl(passwordPolicy);
|
|
648
|
-
let status = passwordPolicyImpl.validatePassword(password);
|
|
649
649
|
|
|
650
|
-
return
|
|
650
|
+
return auth.validatePassword.call(auth, password, MODULAR_DEPRECATION_ARG);
|
|
651
651
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { fetchPasswordPolicy } from './passwordPolicyApi';
|
|
19
|
+
import { PasswordPolicyImpl } from './PasswordPolicyImpl';
|
|
20
|
+
|
|
21
|
+
const EXPECTED_PASSWORD_POLICY_SCHEMA_VERSION = 1;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Password policy mixin - provides password policy caching and validation.
|
|
25
|
+
* Expects the target object to have: _tenantId, _projectPasswordPolicy,
|
|
26
|
+
* _tenantPasswordPolicies, and app.options.apiKey
|
|
27
|
+
*/
|
|
28
|
+
export const PasswordPolicyMixin = {
|
|
29
|
+
_getPasswordPolicyInternal() {
|
|
30
|
+
if (this._tenantId === null) {
|
|
31
|
+
return this._projectPasswordPolicy;
|
|
32
|
+
}
|
|
33
|
+
return this._tenantPasswordPolicies[this._tenantId];
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
async _updatePasswordPolicy() {
|
|
37
|
+
const response = await fetchPasswordPolicy(this);
|
|
38
|
+
const passwordPolicy = new PasswordPolicyImpl(response);
|
|
39
|
+
if (this._tenantId === null) {
|
|
40
|
+
this._projectPasswordPolicy = passwordPolicy;
|
|
41
|
+
} else {
|
|
42
|
+
this._tenantPasswordPolicies[this._tenantId] = passwordPolicy;
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
async _recachePasswordPolicy() {
|
|
47
|
+
if (this._getPasswordPolicyInternal()) {
|
|
48
|
+
await this._updatePasswordPolicy();
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
async validatePassword(password) {
|
|
53
|
+
if (!this._getPasswordPolicyInternal()) {
|
|
54
|
+
await this._updatePasswordPolicy();
|
|
55
|
+
}
|
|
56
|
+
const passwordPolicy = this._getPasswordPolicyInternal();
|
|
57
|
+
|
|
58
|
+
if (passwordPolicy.schemaVersion !== EXPECTED_PASSWORD_POLICY_SCHEMA_VERSION) {
|
|
59
|
+
throw new Error(
|
|
60
|
+
'auth/unsupported-password-policy-schema-version: The password policy received from the backend uses a schema version that is not supported by this version of the SDK.',
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return passwordPolicy.validatePassword(password);
|
|
65
|
+
},
|
|
66
|
+
};
|
|
@@ -23,8 +23,6 @@
|
|
|
23
23
|
* @throws {Error} Throws an error if the request fails or encounters an issue.
|
|
24
24
|
*/
|
|
25
25
|
export async function fetchPasswordPolicy(auth) {
|
|
26
|
-
let schemaVersion = 1;
|
|
27
|
-
|
|
28
26
|
try {
|
|
29
27
|
// Identity toolkit API endpoint for password policy. Ensure this is enabled on Google cloud.
|
|
30
28
|
const baseURL = 'https://identitytoolkit.googleapis.com/v2/passwordPolicy?key=';
|
|
@@ -37,19 +35,10 @@ export async function fetchPasswordPolicy(auth) {
|
|
|
37
35
|
`firebase.auth().validatePassword(*) failed to fetch password policy from Firebase Console: ${response.statusText}. Details: ${errorDetails}`,
|
|
38
36
|
);
|
|
39
37
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (passwordPolicy.schemaVersion !== schemaVersion) {
|
|
43
|
-
throw new Error(
|
|
44
|
-
`Password policy schema version mismatch. Expected: ${schemaVersion}, received: ${passwordPolicy.schemaVersion}`,
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
return passwordPolicy;
|
|
38
|
+
return await response.json();
|
|
48
39
|
} catch (error) {
|
|
49
40
|
throw new Error(
|
|
50
41
|
`firebase.auth().validatePassword(*) Failed to fetch password policy: ${error.message}`,
|
|
51
42
|
);
|
|
52
43
|
}
|
|
53
44
|
}
|
|
54
|
-
|
|
55
|
-
module.exports = { fetchPasswordPolicy };
|
package/lib/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
module.exports = '23.
|
|
2
|
+
module.exports = '23.7.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-native-firebase/auth",
|
|
3
|
-
"version": "23.
|
|
3
|
+
"version": "23.7.0",
|
|
4
4
|
"author": "Invertase <oss@invertase.io> (http://invertase.io)",
|
|
5
5
|
"description": "React Native Firebase - The authentication module provides an easy-to-use API to integrate an authentication workflow into new and existing applications. React Native Firebase provides access to all Firebase authentication methods and identity providers.",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -27,12 +27,12 @@
|
|
|
27
27
|
"plist": "^3.1.0"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
|
-
"@react-native-firebase/app": "23.
|
|
30
|
+
"@react-native-firebase/app": "23.7.0",
|
|
31
31
|
"expo": ">=47.0.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/plist": "^3.0.5",
|
|
35
|
-
"expo": "^
|
|
35
|
+
"expo": "^54.0.27"
|
|
36
36
|
},
|
|
37
37
|
"peerDependenciesMeta": {
|
|
38
38
|
"expo": {
|
|
@@ -43,5 +43,5 @@
|
|
|
43
43
|
"access": "public",
|
|
44
44
|
"provenance": true
|
|
45
45
|
},
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "2a30c0b1e41a2b239172afd167f98a03fd422f2c"
|
|
47
47
|
}
|
|
@@ -150,6 +150,10 @@ function modifySwiftAppDelegate(contents) {
|
|
|
150
150
|
return null;
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
|
+
const isAlreadyModified = contents.includes(skipOpenUrlForFirebaseAuthBlockSwift);
|
|
154
|
+
if (isAlreadyModified) {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
153
157
|
return contents.replace(pattern, `${fullMatch[0]}${skipOpenUrlForFirebaseAuthBlockSwift}\n`);
|
|
154
158
|
}
|
|
155
159
|
// Search the ExpoConfig plugins array to see if `pluginName` is present
|
|
@@ -183,6 +183,10 @@ export function modifySwiftAppDelegate(contents: string): string | null {
|
|
|
183
183
|
return null;
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
|
+
const isAlreadyModified = contents.includes(skipOpenUrlForFirebaseAuthBlockSwift);
|
|
187
|
+
if (isAlreadyModified) {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
186
190
|
return contents.replace(pattern, `${fullMatch[0]}${skipOpenUrlForFirebaseAuthBlockSwift}\n`);
|
|
187
191
|
}
|
|
188
192
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["./src/index.ts","./src/pluginConfig.ts","./src/ios/index.ts","./src/ios/openUrlFix.ts","./src/ios/urlTypes.ts"],"version":"5.9.
|
|
1
|
+
{"root":["./src/index.ts","./src/pluginConfig.ts","./src/ios/index.ts","./src/ios/openUrlFix.ts","./src/ios/urlTypes.ts"],"version":"5.9.3"}
|