Skip to content

Commit

Permalink
[Auth compat] Fix the way we initialize compat auth. Also fix some br…
Browse files Browse the repository at this point in the history
…oken integration tests (#4653)

* Fix auth compat initialization

* Fix compat lint

* Fix broken node tests

* Formatting

* Remove dead code
  • Loading branch information
sam-gc committed Mar 22, 2021
1 parent 8c56c25 commit fdadf71
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 49 deletions.
1 change: 1 addition & 0 deletions packages-exp/auth-compat-exp/index.node.ts
Expand Up @@ -24,6 +24,7 @@
export * from './index';
import { FetchProvider } from '@firebase/auth-exp/internal';
import * as fetchImpl from 'node-fetch';
import './index';

FetchProvider.initialize(
(fetchImpl.default as unknown) as typeof fetch,
Expand Down
6 changes: 3 additions & 3 deletions packages-exp/auth-compat-exp/index.ts
Expand Up @@ -98,8 +98,8 @@ function registerAuthCompat(instance: _FirebaseNamespace): void {
container => {
// getImmediate for FirebaseApp will always succeed
const app = container.getProvider('app-compat').getImmediate();
const auth = container.getProvider('auth-exp').getImmediate();
return new Auth(app, auth as impl.AuthImpl);
const authProvider = container.getProvider('auth-exp');
return new Auth(app, authProvider);
},
ComponentType.PUBLIC
)
Expand Down Expand Up @@ -136,7 +136,7 @@ function registerAuthCompat(instance: _FirebaseNamespace): void {
.setMultipleInstances(false)
);

instance.registerVersion('auth', version);
instance.registerVersion('auth-compat', version);
}

registerAuthCompat(firebase as _FirebaseNamespace);
2 changes: 1 addition & 1 deletion packages-exp/auth-compat-exp/rollup.config.shared.js
Expand Up @@ -65,7 +65,7 @@ export function getEs5Builds(additionalTypescriptPlugins = {}) {
plugins: es5BuildPlugins,
external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)),
treeshake: {
moduleSideEffects: false
moduleSideEffects: true
}
},
/**
Expand Down
36 changes: 24 additions & 12 deletions packages-exp/auth-compat-exp/src/auth.test.ts
Expand Up @@ -17,6 +17,7 @@

import { FirebaseApp } from '@firebase/app-compat';
import * as exp from '@firebase/auth-exp/internal';
import { Provider } from '@firebase/component';
import { expect, use } from 'chai';
import * as sinon from 'sinon';
import * as sinonChai from 'sinon-chai';
Expand All @@ -31,12 +32,16 @@ describe('auth compat', () => {
context('redirect persistence key storage', () => {
let underlyingAuth: exp.AuthImpl;
let app: FirebaseApp;
let providerStub: sinon.SinonStubbedInstance<Provider<'auth-exp'>>;

beforeEach(() => {
app = { options: { apiKey: 'api-key' } } as FirebaseApp;
underlyingAuth = new exp.AuthImpl(app, {
apiKey: 'api-key'
} as exp.Config);
sinon.stub(underlyingAuth, '_initializeWithPersistence');

providerStub = sinon.createStubInstance(Provider);
});

afterEach(() => {
Expand All @@ -56,7 +61,12 @@ describe('auth compat', () => {
),
'_openRedirect'
);
const authCompat = new Auth(app, underlyingAuth);
providerStub.isInitialized.returns(true);
providerStub.getImmediate.returns(underlyingAuth);
const authCompat = new Auth(
app,
(providerStub as unknown) as Provider<'auth-exp'>
);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
await authCompat.signInWithRedirect(new exp.GoogleAuthProvider());
expect(
Expand All @@ -71,18 +81,20 @@ describe('auth compat', () => {
'firebase:persistence:api-key:undefined',
'none'
);
new Auth(app, underlyingAuth);
providerStub.isInitialized.returns(false);
providerStub.initialize.returns(underlyingAuth);
new Auth(app, (providerStub as unknown) as Provider<'auth-exp'>);
// eslint-disable-next-line @typescript-eslint/no-floating-promises
expect(
underlyingAuth._initializeWithPersistence
).to.have.been.calledWith(
[
exp._getInstance(exp.inMemoryPersistence),
exp._getInstance(exp.indexedDBLocalPersistence),
exp._getInstance(exp.browserLocalPersistence)
],
CompatPopupRedirectResolver
);
expect(providerStub.initialize).to.have.been.calledWith({
options: {
popupRedirectResolver: CompatPopupRedirectResolver,
persistence: [
exp.inMemoryPersistence,
exp.indexedDBLocalPersistence,
exp.browserLocalPersistence
]
}
});
}
});
});
Expand Down
57 changes: 33 additions & 24 deletions packages-exp/auth-compat-exp/src/auth.ts
Expand Up @@ -18,6 +18,7 @@
import { FirebaseApp, _FirebaseService } from '@firebase/app-compat';
import * as exp from '@firebase/auth-exp/internal';
import * as compat from '@firebase/auth-types';
import { Provider } from '@firebase/component';
import { ErrorFn, Observer, Unsubscribe } from '@firebase/util';

import {
Expand All @@ -39,47 +40,55 @@ const _assert: typeof exp._assert = exp._assert;

export class Auth
implements compat.FirebaseAuth, Wrapper<exp.Auth>, _FirebaseService {
// private readonly auth: impl.AuthImpl;
private readonly auth: exp.AuthImpl;

constructor(readonly app: FirebaseApp, private readonly auth: exp.AuthImpl) {
const { apiKey } = app.options;
if (this.auth._deleted) {
constructor(readonly app: FirebaseApp, provider: Provider<'auth-exp'>) {
if (provider.isInitialized()) {
this.auth = provider.getImmediate() as exp.AuthImpl;
return;
}

// Note this is slightly different behavior: in this case, the stored
// persistence is checked *first* rather than last. This is because we want
// to prefer stored persistence type in the hierarchy.
const persistences = _getPersistencesFromRedirect(this.auth);
const { apiKey } = app.options;
// TODO: platform needs to be determined using heuristics
_assert(apiKey, exp.AuthErrorCode.INVALID_API_KEY, {
appName: app.name
});

let persistences: exp.Persistence[] = [exp.inMemoryPersistence];

for (const persistence of [
exp.indexedDBLocalPersistence,
exp.browserLocalPersistence
]) {
if (!persistences.includes(persistence)) {
persistences.push(persistence);
// Only deal with persistences in web environments
if (typeof window !== 'undefined') {
// Note this is slightly different behavior: in this case, the stored
// persistence is checked *first* rather than last. This is because we want
// to prefer stored persistence type in the hierarchy.
persistences = _getPersistencesFromRedirect(apiKey, app.name);

for (const persistence of [
exp.indexedDBLocalPersistence,
exp.browserLocalPersistence
]) {
if (!persistences.includes(persistence)) {
persistences.push(persistence);
}
}
}

const hierarchy = persistences.map<exp.PersistenceInternal>(
exp._getInstance
);

// TODO: platform needs to be determined using heuristics
_assert(apiKey, exp.AuthErrorCode.INVALID_API_KEY, {
appName: app.name
});

this.auth._updateErrorMap(exp.debugErrorMap);

// Only use a popup/redirect resolver in browser environments
const resolver =
typeof window !== 'undefined' ? CompatPopupRedirectResolver : undefined;
this.auth = provider.initialize({
options: {
persistence: persistences,
popupRedirectResolver: resolver
}
}) as exp.AuthImpl;

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

get emulatorConfig(): compat.EmulatorConfig | null {
Expand Down
9 changes: 3 additions & 6 deletions packages-exp/auth-compat-exp/src/persistence.ts
Expand Up @@ -97,18 +97,15 @@ export async function _savePersistenceForRedirect(
}

export function _getPersistencesFromRedirect(
auth: exp.AuthInternal
apiKey: string,
appName: string
): exp.Persistence[] {
const win = getSelfWindow();
if (!win?.sessionStorage) {
return [];
}

const key = exp._persistenceKeyName(
PERSISTENCE_KEY,
auth.config.apiKey,
auth.name
);
const key = exp._persistenceKeyName(PERSISTENCE_KEY, apiKey, appName);
const persistence = win.sessionStorage.getItem(key);

switch (persistence) {
Expand Down
Expand Up @@ -19,8 +19,6 @@ import { expect, use } from 'chai';
import * as chaiAsPromised from 'chai-as-promised';

import firebase from '@firebase/app-compat';
// eslint-disable-next-line import/no-extraneous-dependencies
import '@firebase/auth-compat';
import { FirebaseError } from '@firebase/util';
import {
cleanUpTestInstance,
Expand Down
Expand Up @@ -18,7 +18,6 @@
import { FirebaseError } from '@firebase/util';
import { expect, use } from 'chai';
import firebase from '@firebase/app-compat';
import '@firebase/auth-compat';

import * as chaiAsPromised from 'chai-as-promised';
import {
Expand Down

0 comments on commit fdadf71

Please sign in to comment.