123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.registerHandlers = void 0;
- const url_1 = require("url");
- const operations_1 = require("./operations");
- const errors_1 = require("./errors");
- const widget_ui_1 = require("./widget_ui");
- function registerHandlers(app, getProjectStateByApiKey) {
- app.get(`/emulator/action`, (req, res) => {
- const { mode, oobCode, continueUrl, apiKey, tenantId } = req.query;
- if (!apiKey) {
- return res.status(400).json({
- authEmulator: {
- error: "missing apiKey query parameter",
- instructions: `Please modify the URL to specify an apiKey, such as ...&apiKey=YOUR_API_KEY`,
- },
- });
- }
- if (!oobCode) {
- return res.status(400).json({
- authEmulator: {
- error: "missing oobCode query parameter",
- instructions: `Please modify the URL to specify an oobCode, such as ...&oobCode=YOUR_OOB_CODE`,
- },
- });
- }
- const state = getProjectStateByApiKey(apiKey, tenantId);
- switch (mode) {
- case "recoverEmail": {
- const oob = state.validateOobCode(oobCode);
- const RETRY_INSTRUCTIONS = "If you're trying to test the reverting email flow, try changing the email again to generate a new link.";
- if ((oob === null || oob === void 0 ? void 0 : oob.requestType) !== "RECOVER_EMAIL") {
- return res.status(400).json({
- authEmulator: {
- error: `Requested mode does not match the OOB code provided.`,
- instructions: RETRY_INSTRUCTIONS,
- },
- });
- }
- try {
- const resp = (0, operations_1.setAccountInfoImpl)(state, {
- oobCode,
- });
- const email = resp.email;
- return res.status(200).json({
- authEmulator: { success: `The email has been successfully reset.`, email },
- });
- }
- catch (e) {
- if (e instanceof errors_1.NotImplementedError ||
- (e instanceof errors_1.BadRequestError && e.message === "INVALID_OOB_CODE")) {
- return res.status(400).json({
- authEmulator: {
- error: `Your request to revert your email has expired or the link has already been used.`,
- instructions: RETRY_INSTRUCTIONS,
- },
- });
- }
- else {
- throw e;
- }
- }
- }
- case "resetPassword": {
- const oob = state.validateOobCode(oobCode);
- if ((oob === null || oob === void 0 ? void 0 : oob.requestType) !== "PASSWORD_RESET") {
- return res.status(400).json({
- authEmulator: {
- error: `Your request to reset your password has expired or the link has already been used.`,
- instructions: `Try resetting your password again.`,
- },
- });
- }
- if (!req.query.newPassword) {
- return res.status(400).json({
- authEmulator: {
- error: "missing newPassword query parameter",
- instructions: `To reset the password for ${oob.email}, send an HTTP GET request to the following URL.`,
- instructions2: "You may use a web browser or any HTTP client, such as curl.",
- urlTemplate: `${oob.oobLink}&newPassword=NEW_PASSWORD_HERE`,
- },
- });
- }
- else if (req.query.newPassword === "NEW_PASSWORD_HERE") {
- return res.status(400).json({
- authEmulator: {
- error: "newPassword must be something other than 'NEW_PASSWORD_HERE'",
- instructions: "The string 'NEW_PASSWORD_HERE' is just a placeholder.",
- instructions2: "Please change the URL to specify a new password instead.",
- urlTemplate: `${oob.oobLink}&newPassword=NEW_PASSWORD_HERE`,
- },
- });
- }
- const { email } = (0, operations_1.resetPassword)(state, {
- oobCode,
- newPassword: req.query.newPassword,
- });
- if (continueUrl) {
- return res.redirect(303, continueUrl);
- }
- else {
- return res.status(200).json({
- authEmulator: { success: `The password has been successfully updated.`, email },
- });
- }
- }
- case "verifyEmail": {
- try {
- const { email } = (0, operations_1.setAccountInfoImpl)(state, { oobCode });
- if (continueUrl) {
- return res.redirect(303, continueUrl);
- }
- else {
- return res.status(200).json({
- authEmulator: { success: `The email has been successfully verified.`, email },
- });
- }
- }
- catch (e) {
- if (e instanceof errors_1.NotImplementedError ||
- (e instanceof errors_1.BadRequestError && e.message === "INVALID_OOB_CODE")) {
- return res.status(400).json({
- authEmulator: {
- error: `Your request to verify your email has expired or the link has already been used.`,
- instructions: `Try verifying your email again.`,
- },
- });
- }
- else {
- throw e;
- }
- }
- }
- case "signIn": {
- if (!continueUrl) {
- return res.status(400).json({
- authEmulator: {
- error: "Missing continueUrl query parameter",
- instructions: `To sign in, append &continueUrl=YOUR_APP_URL to the link.`,
- },
- });
- }
- const redirectTo = new url_1.URL(continueUrl);
- for (const name of Object.keys(req.query)) {
- if (name !== "continueUrl") {
- const query = req.query[name];
- if (typeof query === "string") {
- redirectTo.searchParams.set(name, query);
- }
- }
- }
- return res.redirect(303, redirectTo.toString());
- }
- default:
- return res.status(400).json({ authEmulator: { error: "Invalid mode" } });
- }
- });
- app.get(`/emulator/auth/handler`, (req, res) => {
- res.set("Content-Type", "text/html; charset=utf-8");
- const apiKey = req.query.apiKey;
- const providerId = req.query.providerId;
- const tenantId = req.query.tenantId;
- if (!apiKey || !providerId) {
- return res.status(400).json({
- authEmulator: {
- error: "missing apiKey or providerId query parameters",
- },
- });
- }
- const state = getProjectStateByApiKey(apiKey, tenantId);
- const providerInfos = state.listProviderInfosByProviderId(providerId);
- const options = providerInfos
- .map((info) => `<li class="js-reuse-account mdc-list-item mdc-ripple-upgraded" tabindex="0" data-id-token="${encodeURIComponent(createFakeClaims(info))}">
- <span class="mdc-list-item__ripple"></span>
- ${info.photoUrl
- ? `
- <span class="mdc-list-item__graphic profile-photo" style="background-image: url('${info.photoUrl}')"></span>`
- : `
- <span class="mdc-list-item__graphic material-icons" aria-hidden=true>person</span>`}
- <span class="mdc-list-item__text"><span class="mdc-list-item__primary-text">${info.displayName || "(No display name)"}</span>
- <span class="mdc-list-item__secondary-text fallback-secondary-text" id="reuse-email">${info.email || ""}</span>
- </li>`)
- .join("\n");
- res.end(widget_ui_1.WIDGET_UI.replace(widget_ui_1.PROVIDERS_LIST_PLACEHOLDER, options));
- });
- app.get(`/emulator/auth/iframe`, (req, res) => {
- res.set("Content-Type", "text/html; charset=utf-8");
- res.end(`<!DOCTYPE html>
- <meta charset="utf-8">
- <title>Auth Emulator Helper Iframe</title>
- <script>
- // TODO: Support older browsers where URLSearchParams is not available.
- var query = new URLSearchParams(location.search);
- var apiKey = query.get('apiKey');
- var appName = query.get('appName');
- if (!apiKey || !appName) {
- alert('Auth Emulator Internal Error: Missing query params apiKey or appName for iframe.');
- }
- var storageKey = apiKey + ':' + appName;
-
- var parentContainer = null;
-
- window.addEventListener('message', function (e) {
- if (typeof e.data === 'object' && e.data.eventType === 'sendAuthEvent') {
- if (!e.data.data.storageKey === storageKey) {
- return alert('Auth Emulator Internal Error: Received request with mismatching storageKey');
- }
- var authEvent = e.data.data.authEvent;
- if (parentContainer) {
- sendAuthEvent(authEvent);
- } else {
- // Store it first, and initFrameMessaging() below will pick it up.
- sessionStorage['firebase:redirectEvent:' + storageKey] =
- JSON.stringify(authEvent);
- }
- }
- });
-
- function initFrameMessaging() {
- parentContainer = gapi.iframes.getContext().getParentIframe();
- parentContainer.register('webStorageSupport', function() {
- // We must reply to this event, or the JS SDK will not continue with the
- // popup flow. Web storage support is not actually needed though.
- return { status: 'ACK', webStorageSupport: true };
- }, gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER);
-
- var authEvent = null;
- var storedEvent = sessionStorage['firebase:redirectEvent:' + storageKey];
- if (storedEvent) {
- try {
- authEvent = JSON.parse(storedEvent);
- } catch (_) {
- return alert('Auth Emulator Internal Error: Invalid stored event.');
- }
- }
- sendAuthEvent(authEvent);
- delete sessionStorage['firebase:redirectEvent:' + storageKey];
- }
-
- function sendAuthEvent(authEvent) {
- parentContainer.send('authEvent', {
- type: 'authEvent',
- authEvent: authEvent || { type: 'unknown', error: { code: 'auth/no-auth-event' } },
- }, function(responses) {
- if (!responses || !responses.length ||
- responses[responses.length - 1].status !== 'ACK') {
- return alert("Auth Emulator Internal Error: Sending authEvent failed.");
- }
- }, gapi.iframes.CROSS_ORIGIN_IFRAMES_FILTER);
- }
-
- window.gapi_onload = function () {
- gapi.load('gapi.iframes', {
- callback: initFrameMessaging,
- timeout: 10000,
- ontimeout: function () {
- return alert("Auth Emulator Internal Error: Error loading gapi.iframe! Please check your Internet connection.");
- },
- });
- }
- </script>
- <script src="https://apis.google.com/js/api.js"></script>
- `);
- });
- }
- exports.registerHandlers = registerHandlers;
- function createFakeClaims(info) {
- const claims = {
- sub: info.rawId,
- iss: "",
- aud: "",
- exp: 0,
- iat: 0,
- name: info.displayName,
- screen_name: info.screenName,
- email: info.email,
- email_verified: true,
- picture: info.photoUrl,
- };
- return JSON.stringify(claims);
- }
|