voluptasmollitia
Version:
Monorepo for the Firebase JavaScript SDK
164 lines (157 loc) • 5.21 kB
text/typescript
/**
* @license
* Copyright 2018 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { initializeApp } from '@firebase/app-exp';
import {
createUserWithEmailAndPassword,
fetchSignInMethodsForEmail,
getAuth,
GoogleAuthProvider,
signInAnonymously,
signInWithCredential,
signInWithEmailAndPassword,
updateProfile,
User
} from '@firebase/auth-exp';
import { config } from '../config';
/**
* @fileoverview Web worker for Firebase Auth test app application. The
* web worker tries to run operations on the Auth instance for testing purposes.
*/
// Initialize the Firebase app in the web worker.
const app = initializeApp(config);
const auth = getAuth(app);
/**
* Returns a promise that resolves with an ID token if available.
* @return {!Promise<?string>} The promise that resolves with an ID token if
* available. Otherwise, the promise resolves with null.
*/
function getIdToken(): Promise<string | null> {
return new Promise(resolve => {
auth.onAuthStateChanged((user: User | null) => {
if (user) {
user
.getIdToken()
.then(resolve)
.catch(() => {
resolve(null);
});
} else {
resolve(null);
}
});
});
}
/**
* Runs various Firebase Auth tests in a web worker environment and confirms the
* expected behavior. This is useful for manual testing in different browsers.
* @param {string} googleIdToken The Google ID token to sign in with.
* @return {!Promise<void>} A promise that resolves when all tests run
* successfully.
*/
async function runWorkerTests(googleIdToken: string): Promise<void> {
const expectedDisplayName = 'Test User';
const oauthCredential = GoogleAuthProvider.credential(googleIdToken);
const email =
'user' +
Math.floor(Math.random() * 10000000000).toString() +
'@example.com';
const pass = 'password';
auth.useDeviceLanguage();
let credential = await signInAnonymously(auth);
if (!credential.user.uid) {
throw new Error('signInAnonymously unexpectedly failed!');
}
await updateProfile(credential.user, { displayName: expectedDisplayName });
if (auth.currentUser!.displayName !== expectedDisplayName) {
throw new Error('Profile update failed!');
}
await auth.currentUser!.delete();
if (auth.currentUser) {
throw new Error('currentUser.delete unexpectedly failed!');
}
credential = await createUserWithEmailAndPassword(auth, email, pass);
if (credential.user.email !== email) {
throw new Error('createUserWithEmailAndPassword unexpectedly failed!');
}
const providers = await fetchSignInMethodsForEmail(auth, email);
if (providers.length === 0 || providers[0] !== 'password') {
throw new Error('fetchSignInMethodsForEmail failed!');
}
credential = await signInWithEmailAndPassword(auth, email, pass);
if (credential.user.email !== email) {
throw new Error('signInWithEmailAndPassword unexpectedly failed!');
}
await credential.user.delete();
const userCredential = await signInWithCredential(auth, oauthCredential);
if (!userCredential.user || !userCredential.user.uid) {
throw new Error('signInWithCredential unexpectedly failed!');
}
const googleCredential = GoogleAuthProvider.credentialFromResult(
userCredential
);
if (!googleCredential) {
throw new Error('signInWithCredential unexpectedly failed!');
}
await auth.signOut();
if (auth.currentUser) {
throw new Error('signOut unexpectedly failed!');
}
}
/**
* Handles the incoming message from the main script.
* @param {!MessageEvent} e The message event received.
*/
self.onmessage = (e: MessageEvent) => {
// https://github.com/microsoft/TypeScript/issues/12657
const ctx = self as DedicatedWorkerGlobalScope;
if (e?.data.type) {
switch (e.data.type) {
case 'GET_USER_INFO':
getIdToken()
.then(idToken => {
ctx.postMessage({
type: e.data.type,
idToken,
uid: auth.currentUser?.uid
});
})
.catch(error => {
console.log(error);
});
break;
case 'RUN_TESTS':
runWorkerTests(e.data.googleIdToken)
.then(() => {
ctx.postMessage({
type: e.data.type,
status: 'success'
});
})
.catch(error => {
// DataCloneError when postMessaging in IE11 and 10.
ctx.postMessage({
type: e.data.type,
status: 'failure',
error: error.code ? error : error.message
});
});
break;
default:
ctx.postMessage({});
}
}
};