Skip to content

Commit 13c281f

Browse files
authored
Merge branch 'master' into ys/auth-exp-tab-sync
2 parents 9f4b563 + 05f5bf3 commit 13c281f

File tree

189 files changed

+3057
-2731
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

189 files changed

+3057
-2731
lines changed

.changeset/cyan-wasps-worry.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@firebase/util": patch
3+
---
4+
5+
Added a utility function and type for compat interop API

packages-exp/auth-compat-exp/index.node.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
export * from './index';
2525
import { FetchProvider } from '@firebase/auth-exp/internal';
2626
import * as fetchImpl from 'node-fetch';
27+
import './index';
2728

2829
FetchProvider.initialize(
2930
(fetchImpl.default as unknown) as typeof fetch,

packages-exp/auth-compat-exp/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ function registerAuthCompat(instance: _FirebaseNamespace): void {
9898
container => {
9999
// getImmediate for FirebaseApp will always succeed
100100
const app = container.getProvider('app-compat').getImmediate();
101-
const auth = container.getProvider('auth-exp').getImmediate();
102-
return new Auth(app, auth as impl.AuthImpl);
101+
const authProvider = container.getProvider('auth-exp');
102+
return new Auth(app, authProvider);
103103
},
104104
ComponentType.PUBLIC
105105
)
@@ -136,7 +136,7 @@ function registerAuthCompat(instance: _FirebaseNamespace): void {
136136
.setMultipleInstances(false)
137137
);
138138

139-
instance.registerVersion('auth', version);
139+
instance.registerVersion('auth-compat', version);
140140
}
141141

142142
registerAuthCompat(firebase as _FirebaseNamespace);

packages-exp/auth-compat-exp/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
"test:browser:integration": "karma start --single-run --integration",
2626
"test:node": "ts-node -O '{\"module\": \"commonjs\", \"target\": \"es6\"}' scripts/run_node_tests.ts",
2727
"test:node:integration": "ts-node -O '{\"module\": \"commonjs\", \"target\": \"es6\"}' scripts/run_node_tests.ts --integration",
28-
"test:integration": "run-s test:browser:integration test:node:integration"
28+
"test:webdriver": "rollup -c test/integration/webdriver/static/rollup.config.js && ts-node -O '{\"module\": \"commonjs\", \"target\": \"es6\"}' scripts/run_node_tests.ts --webdriver",
29+
"test:integration": "run-s test:browser:integration test:node:integration test:webdriver"
2930
},
3031
"peerDependencies": {
3132
"@firebase/app-compat": "0.x"
@@ -41,8 +42,8 @@
4142
"license": "Apache-2.0",
4243
"devDependencies": {
4344
"@firebase/app-compat": "0.x",
44-
"rollup": "2.35.1",
4545
"@rollup/plugin-json": "4.1.0",
46+
"rollup": "^2.35.1",
4647
"rollup-plugin-replace": "2.2.0",
4748
"rollup-plugin-typescript2": "0.29.0",
4849
"typescript": "4.2.2"

packages-exp/auth-compat-exp/rollup.config.shared.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export function getEs5Builds(additionalTypescriptPlugins = {}) {
6565
plugins: es5BuildPlugins,
6666
external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)),
6767
treeshake: {
68-
moduleSideEffects: false
68+
moduleSideEffects: true
6969
}
7070
},
7171
/**

packages-exp/auth-compat-exp/scripts/run_node_tests.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,14 @@ const nyc = resolve(__dirname, '../../../node_modules/.bin/nyc');
3333
const mocha = resolve(__dirname, '../../../node_modules/.bin/mocha');
3434

3535
process.env.TS_NODE_COMPILER_OPTIONS = '{"module":"commonjs", "target": "es6"}';
36+
process.env.COMPAT_LAYER = 'true';
3637

3738
let testConfig = ['src/**/*.test.ts'];
3839

3940
if (argv.integration) {
4041
testConfig = ['test/integration/flows/**.test.ts'];
4142
} else if (argv.webdriver) {
42-
testConfig = ['test/integration/webdriver/**.test.ts', '--delay'];
43+
testConfig = ['../auth-exp/test/integration/webdriver/*.test.ts', '--delay'];
4344
}
4445

4546
let args = [

packages-exp/auth-compat-exp/src/auth.test.ts

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import { FirebaseApp } from '@firebase/app-compat';
1919
import * as exp from '@firebase/auth-exp/internal';
20+
import { Provider } from '@firebase/component';
2021
import { expect, use } from 'chai';
2122
import * as sinon from 'sinon';
2223
import * as sinonChai from 'sinon-chai';
@@ -31,12 +32,16 @@ describe('auth compat', () => {
3132
context('redirect persistence key storage', () => {
3233
let underlyingAuth: exp.AuthImpl;
3334
let app: FirebaseApp;
35+
let providerStub: sinon.SinonStubbedInstance<Provider<'auth-exp'>>;
36+
3437
beforeEach(() => {
3538
app = { options: { apiKey: 'api-key' } } as FirebaseApp;
3639
underlyingAuth = new exp.AuthImpl(app, {
3740
apiKey: 'api-key'
3841
} as exp.Config);
3942
sinon.stub(underlyingAuth, '_initializeWithPersistence');
43+
44+
providerStub = sinon.createStubInstance(Provider);
4045
});
4146

4247
afterEach(() => {
@@ -56,7 +61,12 @@ describe('auth compat', () => {
5661
),
5762
'_openRedirect'
5863
);
59-
const authCompat = new Auth(app, underlyingAuth);
64+
providerStub.isInitialized.returns(true);
65+
providerStub.getImmediate.returns(underlyingAuth);
66+
const authCompat = new Auth(
67+
app,
68+
(providerStub as unknown) as Provider<'auth-exp'>
69+
);
6070
// eslint-disable-next-line @typescript-eslint/no-floating-promises
6171
await authCompat.signInWithRedirect(new exp.GoogleAuthProvider());
6272
expect(
@@ -71,18 +81,20 @@ describe('auth compat', () => {
7181
'firebase:persistence:api-key:undefined',
7282
'none'
7383
);
74-
new Auth(app, underlyingAuth);
84+
providerStub.isInitialized.returns(false);
85+
providerStub.initialize.returns(underlyingAuth);
86+
new Auth(app, (providerStub as unknown) as Provider<'auth-exp'>);
7587
// eslint-disable-next-line @typescript-eslint/no-floating-promises
76-
expect(
77-
underlyingAuth._initializeWithPersistence
78-
).to.have.been.calledWith(
79-
[
80-
exp._getInstance(exp.inMemoryPersistence),
81-
exp._getInstance(exp.indexedDBLocalPersistence),
82-
exp._getInstance(exp.browserLocalPersistence)
83-
],
84-
CompatPopupRedirectResolver
85-
);
88+
expect(providerStub.initialize).to.have.been.calledWith({
89+
options: {
90+
popupRedirectResolver: CompatPopupRedirectResolver,
91+
persistence: [
92+
exp.inMemoryPersistence,
93+
exp.indexedDBLocalPersistence,
94+
exp.browserLocalPersistence
95+
]
96+
}
97+
});
8698
}
8799
});
88100
});

packages-exp/auth-compat-exp/src/auth.ts

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import { FirebaseApp, _FirebaseService } from '@firebase/app-compat';
1919
import * as exp from '@firebase/auth-exp/internal';
2020
import * as compat from '@firebase/auth-types';
21+
import { Provider } from '@firebase/component';
2122
import { ErrorFn, Observer, Unsubscribe } from '@firebase/util';
2223

2324
import {
@@ -33,53 +34,63 @@ import {
3334
convertConfirmationResult,
3435
convertCredential
3536
} from './user_credential';
36-
import { unwrap, Wrapper } from './wrap';
37+
import { ReverseWrapper, unwrap, Wrapper } from './wrap';
3738

3839
const _assert: typeof exp._assert = exp._assert;
3940

4041
export class Auth
4142
implements compat.FirebaseAuth, Wrapper<exp.Auth>, _FirebaseService {
42-
// private readonly auth: impl.AuthImpl;
43+
private readonly auth: exp.AuthImpl;
4344

44-
constructor(readonly app: FirebaseApp, private readonly auth: exp.AuthImpl) {
45-
const { apiKey } = app.options;
46-
if (this.auth._deleted) {
45+
constructor(readonly app: FirebaseApp, provider: Provider<'auth-exp'>) {
46+
if (provider.isInitialized()) {
47+
this.auth = provider.getImmediate() as exp.AuthImpl;
48+
this.linkUnderlyingAuth();
4749
return;
4850
}
4951

50-
// Note this is slightly different behavior: in this case, the stored
51-
// persistence is checked *first* rather than last. This is because we want
52-
// to prefer stored persistence type in the hierarchy.
53-
const persistences = _getPersistencesFromRedirect(this.auth);
52+
const { apiKey } = app.options;
53+
// TODO: platform needs to be determined using heuristics
54+
_assert(apiKey, exp.AuthErrorCode.INVALID_API_KEY, {
55+
appName: app.name
56+
});
57+
58+
let persistences: exp.Persistence[] = [exp.inMemoryPersistence];
59+
60+
// Only deal with persistences in web environments
61+
if (typeof window !== 'undefined') {
62+
// Note this is slightly different behavior: in this case, the stored
63+
// persistence is checked *first* rather than last. This is because we want
64+
// to prefer stored persistence type in the hierarchy.
65+
persistences = _getPersistencesFromRedirect(apiKey, app.name);
5466

55-
for (const persistence of [
56-
exp.indexedDBLocalPersistence,
57-
exp.browserLocalPersistence
58-
]) {
59-
if (!persistences.includes(persistence)) {
60-
persistences.push(persistence);
67+
for (const persistence of [
68+
exp.indexedDBLocalPersistence,
69+
exp.browserLocalPersistence
70+
]) {
71+
if (!persistences.includes(persistence)) {
72+
persistences.push(persistence);
73+
}
6174
}
6275
}
6376

64-
const hierarchy = persistences.map<exp.PersistenceInternal>(
65-
exp._getInstance
66-
);
67-
6877
// TODO: platform needs to be determined using heuristics
6978
_assert(apiKey, exp.AuthErrorCode.INVALID_API_KEY, {
7079
appName: app.name
7180
});
7281

73-
this.auth._updateErrorMap(exp.debugErrorMap);
74-
7582
// Only use a popup/redirect resolver in browser environments
7683
const resolver =
7784
typeof window !== 'undefined' ? CompatPopupRedirectResolver : undefined;
85+
this.auth = provider.initialize({
86+
options: {
87+
persistence: persistences,
88+
popupRedirectResolver: resolver
89+
}
90+
}) as exp.AuthImpl;
7891

79-
// This promise is intended to float; auth initialization happens in the
80-
// background, meanwhile the auth object may be used by the app.
81-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
82-
this.auth._initializeWithPersistence(hierarchy, resolver);
92+
this.auth._updateErrorMap(exp.debugErrorMap);
93+
this.linkUnderlyingAuth();
8394
}
8495

8596
get emulatorConfig(): compat.EmulatorConfig | null {
@@ -208,7 +219,9 @@ export class Auth
208219
break;
209220
case Persistence.LOCAL:
210221
// Not using isIndexedDBAvailable() since it only checks if indexedDB is defined.
211-
const isIndexedDBFullySupported = await (exp.indexedDBLocalPersistence as exp.PersistenceInternal)._isAvailable();
222+
const isIndexedDBFullySupported = await exp
223+
._getInstance<exp.PersistenceInternal>(exp.indexedDBLocalPersistence)
224+
._isAvailable();
212225
converted = isIndexedDBFullySupported
213226
? exp.indexedDBLocalPersistence
214227
: exp.browserLocalPersistence;
@@ -321,6 +334,9 @@ export class Auth
321334
_delete(): Promise<void> {
322335
return this.auth._delete();
323336
}
337+
private linkUnderlyingAuth(): void {
338+
((this.auth as unknown) as ReverseWrapper<Auth>).wrapped = () => this;
339+
}
324340
}
325341

326342
function wrapObservers(

packages-exp/auth-compat-exp/src/persistence.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,18 +97,15 @@ export async function _savePersistenceForRedirect(
9797
}
9898

9999
export function _getPersistencesFromRedirect(
100-
auth: exp.AuthInternal
100+
apiKey: string,
101+
appName: string
101102
): exp.Persistence[] {
102103
const win = getSelfWindow();
103104
if (!win?.sessionStorage) {
104105
return [];
105106
}
106107

107-
const key = exp._persistenceKeyName(
108-
PERSISTENCE_KEY,
109-
auth.config.apiKey,
110-
auth.name
111-
);
108+
const key = exp._persistenceKeyName(PERSISTENCE_KEY, apiKey, appName);
112109
const persistence = win.sessionStorage.getItem(key);
113110

114111
switch (persistence) {

packages-exp/auth-compat-exp/src/popup_redirect.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,23 +39,17 @@ export class CompatPopupRedirectResolver
3939
) => Promise<exp.UserCredential | null> = exp._getRedirectResult;
4040

4141
async _initialize(auth: exp.AuthImpl): Promise<exp.EventManager> {
42-
if (this.underlyingResolver) {
43-
return this.underlyingResolver._initialize(auth);
44-
}
45-
46-
// We haven't yet determined whether or not we're in Cordova; go ahead
47-
// and determine that state now.
48-
const isCordova = await _isCordova();
49-
this.underlyingResolver = isCordova ? CORDOVA_RESOLVER : BROWSER_RESOLVER;
42+
await this.selectUnderlyingResolver();
5043
return this.assertedUnderlyingResolver._initialize(auth);
5144
}
5245

53-
_openPopup(
46+
async _openPopup(
5447
auth: exp.AuthImpl,
5548
provider: exp.AuthProvider,
5649
authType: exp.AuthEventType,
5750
eventId?: string
5851
): Promise<exp.AuthPopup> {
52+
await this.selectUnderlyingResolver();
5953
return this.assertedUnderlyingResolver._openPopup(
6054
auth,
6155
provider,
@@ -64,12 +58,13 @@ export class CompatPopupRedirectResolver
6458
);
6559
}
6660

67-
_openRedirect(
61+
async _openRedirect(
6862
auth: exp.AuthImpl,
6963
provider: exp.AuthProvider,
7064
authType: exp.AuthEventType,
7165
eventId?: string
7266
): Promise<void> {
67+
await this.selectUnderlyingResolver();
7368
return this.assertedUnderlyingResolver._openRedirect(
7469
auth,
7570
provider,
@@ -97,4 +92,15 @@ export class CompatPopupRedirectResolver
9792
_assert(this.underlyingResolver, exp.AuthErrorCode.INTERNAL_ERROR);
9893
return this.underlyingResolver;
9994
}
95+
96+
private async selectUnderlyingResolver(): Promise<void> {
97+
if (this.underlyingResolver) {
98+
return;
99+
}
100+
101+
// We haven't yet determined whether or not we're in Cordova; go ahead
102+
// and determine that state now.
103+
const isCordova = await _isCordova();
104+
this.underlyingResolver = isCordova ? CORDOVA_RESOLVER : BROWSER_RESOLVER;
105+
}
100106
}

0 commit comments

Comments
 (0)