Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@skava/packages / core / auth / session / container.js
Size: Mime:
import * as tslib_1 from "tslib";
// modules/libs
import { oneRouter } from '@skava/router';
import { isString } from 'exotic';
import { when, computed } from 'xmobx/mobx';
// import * as cookiez from '@skava/cookies'
// import {
//   has as hasCookie,
//   get as getCookie,
//   renewCache,
//   config as cookieLibConfig,
// } from '@skava/cookies'
import { cookies } from '@skava/cookies';
import { isErrorLikeResponse } from '@skava/is-error-like-response';
import { ObservableContainer } from '@skava/packages/libraries/observable-container';
// ===========================
// state... SHOULD NOT IMPORT SO MANY IN HERE, ENSURE THEY DO NOT IMPORT EACH OTHER
// @example @issue before
// session <====> cart
// session <====> shoppingList
// ===========================
// @note => user/payments => session
import { userContainer } from '@skava/packages/core/auth/user/container';
import { toastMessage, responseMessage } from '@skava/packages/core/notifications';
import { errorContainer } from '@skava/packages/core/notifications';
// ========= @@packages @@modularization @@modules ===
// was importing this, changed to .apis as a split to avoid that
import { cartContainer } from '@skava/packages/core/cart/state/containers';
import { listContainer, listContainerApi, saveForLaterContainer, shoppingListContainer, favoritesContainer, } from '@skava/packages/features/Lists/state';
import { authenticationSwitchContainer } from '@skava/packages/features/Authentication/container';
// ========= @@packages @@modularization @@modules ===
// domain config
import { cookieConfig } from 'src/bootstrap/api/config';
import { config as appConfig } from 'src/bootstrap/config';
import { sessionApis } from './container.apis';
import { toStatus, fromResponseToLoginToast, toSyncListResponse, checkIsSessionExpired, isRegisterSuccess, toBagResponse, toFavoritesResponse, toSaveForLaterResponse, mapCookiesOnResponse, isLoginSuccess, createRecentlyViewedList, toUserProfileResponse, clearCookies, checkSessionExpiredOnMyAccount, } from './deps';
import { logoutBinding } from './bindings';
// issue with v4 cookies
if (typeof window === 'object') {
    // cookieLibConfig.set('document', document)
    // renewCache()
    window.Cookiez = cookies;
}
const hasCookie = cookies.has;
const getCookie = cookies.get;
const renewCache = cookies.renewCache;
class SessionContainer extends ObservableContainer {
    constructor() {
        super(...arguments);
        this.navigateBackTo = '';
        this.registerUser = async (data, securityParams) => {
            const user = await sessionApis
                .registerUser(data, securityParams)
                // .then(this.mapCookiesOnResponse)
                // .then(() => {
                //   // now this happens 2x
                //   sessionApis.createList().then(toListResponse)
                //   sessionApis.createSaveForLater().then(toListResponse)
                //   sessionApis.viewBag().then(toBagResponse)
                // })
                .then(this.handleRegisterResponse)
                .catch(this.handleError);
            /**
             * @todo this should be an array @@perf
             */
            let profile = '';
            let security = '';
            const userStatus = toStatus(user);
            if (userStatus === responseMessage.accountCreationSuccess ||
                userStatus === responseMessage.registerMailFailure) {
                profile = await userContainer
                    .fetchUserLiteProfile()
                    .then(toUserProfileResponse)
                    .then(async (response) => {
                    if (this.isRegisteredUser) {
                        console.log('registerUser createSaveForLaterList');
                        await this.getAllListAPI();
                    }
                    console.log('Loaded User Profile');
                    userContainer.updateFrom(response);
                    // this.omniStore.loadUser(response)
                    this.navigateToLoginSuccess();
                })
                    .catch(this.handleError);
                if (process.env.API_LAYER === 'Stream') {
                    security = await sessionApis.updateSecurity(securityParams, true);
                }
                // .then((response: unknown) => {
                //   console.log('security Question response', response)
                //   userContainer.updateFrom(response)
                // })
            }
            // may not want to do it this way
            // may want to show a loader in interfacestore
            // & then go to the other page
            // oneRouter.replace('/myaccount')
            return Promise.all([user, profile, security]).then(result => {
                console.log(result);
            });
        };
        this.getAllListAPI = async () => {
            const response = await listContainerApi.getAllList().then((listResponse) => {
                favoritesContainer.checkAndUpdateFavorites(listResponse);
                shoppingListContainer.updateFrom(listResponse);
                saveForLaterContainer.createSaveForLaterList(listResponse);
            });
            return response;
        };
        /**
         * @todo @fixme this is to be done on graphql side!!!
         */
        this.adminRegisterAccount = async (data) => {
            const registerData = {
                firstName: data['first-name'],
                lastName: data['last-name'],
                phoneNumber: data['phone-number'],
                email: data.email,
                name: data['organization-name'],
                // password: '',
                street1: data['address-line-one'],
                street2: data['address-line-two'] || '',
                street3: '',
                city: data.city,
                country: data.country,
                state: data.state,
                county: '',
                zipCode: data.postalCode,
                taxId: data['tax-identifier'],
                dunsNumber: isString(data.duns) ? data.duns : '',
            };
            const response = await sessionApis.adminRegisterAccount(registerData);
            if (isErrorLikeResponse(response)) {
                errorContainer.setError({
                    errorMessage: response.responseMessage || '',
                });
            }
            else {
                oneRouter.update('/');
                errorContainer.setError({
                    errorMessage: toastMessage.registerSuccess,
                });
            }
        };
        this.updateProfile = async (profileData) => {
            const response = await sessionApis.updateProfile(profileData).catch(this.handleError);
            this.fetchProfile();
            return response;
            // .then(this.fetchProfile)
        };
        this.updateSecurity = async (data) => {
            const response = await sessionApis.updateSecurity(data).catch(this.handleError);
            return response;
        };
        this.getSecurityQuestions = async (data) => {
            const response = await sessionApis.getSecurityQuestions(data).catch(this.handleError);
            return response;
        };
        this.resetPasswordThroughSms = async (data) => {
            const response = await sessionApis.resetPasswordThroughSms(data).catch(this.handleError);
            return response;
        };
        this.resetPasswordThroughEmail = async (data) => {
            const response = await sessionApis.resetPasswordThroughEmail(data).catch(this.handleError);
            return response;
        };
        this.validateByEmail = async (data) => {
            const response = await sessionApis.validateByEmail(data).catch(this.handleError);
            return response;
        };
        this.userActivation = async (data) => {
            const response = await sessionApis.userActivation(data).catch(this.handleError);
            return response;
        };
        this.resetPasswordThroughSecurityQuestions = async (data) => {
            const response = await sessionApis
                .resetPasswordThroughSecurityQuestions(data)
                .catch(this.handleError);
            return response;
        };
        this.updatePassword = async (password) => {
            const response = await sessionApis.updatePassword(password).catch(this.handleError);
            return response;
        };
        // @todo - use routes here so it is configurable in 1 place
        this.registerGuestUser = async () => {
            if (this.isOrchestrationGuestUser || this.isGuestUser) {
                console.log('Already a guest!');
                return false;
            }
            else {
                console.log('No active user found creating guest');
                const guest = await sessionApis.registerGuestUser();
                const profile = await userContainer
                    .fetchUserLiteProfile()
                    .then(toUserProfileResponse)
                    .then((response) => {
                    userContainer.updateFrom(response);
                })
                    .then(createRecentlyViewedList);
                await favoritesContainer.createFavoritesList();
                await saveForLaterContainer.createDefaultListForSave();
                return Promise.all([guest, profile]).then(result => {
                    if (typeof window === 'object') {
                        console.log('[Cookie Monster]', 'Registered Guest User', window.document.cookie);
                    }
                    // return result
                });
            }
        };
        /**
         * @todo show toast
         */
        this.logOut = async () => {
            const response = await logoutBinding();
            clearCookies();
            // oneRouter.replace('/logout')
            // oneRouter.reload()
            errorContainer.setError({
                errorMessage: 'Signed out',
            });
            // window.location.reload()
            // return response.data.logOut
        };
        this.handleLoginResponse = (response) => {
            const isLoginSuccessful = isLoginSuccess(response);
            if (isLoginSuccessful) {
                // console.log('You are logged in')
                // errorContainer.setMessage('Successfully signed in')
                mapCookiesOnResponse(response);
                // @todo this code used for clearing favorites of guest when signed in
                // remove this code when list merge is implemented
                // ^ @jai
                // favoritesContainer.removeFromFavorites()
            }
            else {
                authenticationSwitchContainer.gotoFreezeSignIn(response);
                const toastText = fromResponseToLoginToast(response);
                errorContainer.setError({
                    errorMessage: toastText,
                });
                console.log('Something Strange In The Neighborhood', response);
            }
            return isLoginSuccessful;
        };
        this.handleRegisterResponse = (response) => {
            // @todo use isErrorLikeResponse to check response success/Failure
            if (isRegisterSuccess(response)) {
                favoritesContainer.createFavoritesList();
                saveForLaterContainer.createDefaultListForSave();
                // @todo remove this after cart and list merge done @gokul
                // ^ commented out @james @@packages
                // cartContainer.fetched.hasFetchedSaveForLater = false
                // cartContainer.viewCart()
                console.log('User created Successfully');
            }
            else {
                errorContainer.setError({
                    errorMessage: toStatus(response) || '',
                });
                console.log('Something Strange In The User creation', response);
            }
            return response;
        };
        this.logIn = async (data) => {
            if (this.isRegisteredUser) {
                errorContainer.setMessage('Already signed in');
                this.navigateToLoginSuccess();
                return true;
            }
            const loginUser = await sessionApis
                .logIn(data)
                .then(this.handleLoginResponse)
                .catch(this.handleError);
            const withProfile = await userContainer
                .fetchUserLiteProfile()
                .then(toUserProfileResponse)
                .then(async (response) => {
                if (this.isRegisteredUser) {
                    console.log('logIn createSaveForLaterList');
                    await this.getAllListAPI();
                    // to fetch save for later again moving from guest flow to signed in
                    // cartContainer.fetched.hasFetchedSaveForLater = false
                    cartContainer.viewCart();
                }
                userContainer.updateFrom(response);
                // @note this is different than others
                // when we load user then return response
                // this.omniStore.loadUser(response)
            })
                .then(() => {
                this.navigateToLoginSuccess();
                return true;
            })
                .catch(this.handleError);
            /**
             * @see https://jira.skava.net/browse/SKB2B-2403
             */
            return Promise.all([loginUser, withProfile]).then(result => {
                return result[0];
                // console.log('Logged In')
            });
        };
        this.loginWithFacebook = async (data) => {
            if (this.isRegisteredUser) {
                this.navigateToLoginSuccess();
                console.log('You are already logged in');
                return;
            }
            await sessionApis
                .loginWithFacebook(data)
                .then(this.handleLoginResponse)
                // @todo if this fails, don't fetch?
                .catch(this.handleError);
            await this.fetchProfile();
            this.navigateToLoginSuccess();
        };
        this.loginWithTwitter = async (data) => {
            if (this.isRegisteredUser) {
                this.navigateToLoginSuccess();
                console.log('You are already logged in');
                return;
            }
            let loginResponse = '';
            await sessionApis
                .loginWithTwitter(data)
                .then((response) => {
                loginResponse = response;
                this.handleLoginResponse(response);
            })
                // @todo if this fails, don't fetch?
                .catch(this.handleError);
            await this.fetchProfile();
            if (isLoginSuccess(loginResponse)) {
                this.navigateToLoginSuccess(true);
            }
        };
        this.loginWithGoogle = async (data) => {
            if (this.isRegisteredUser) {
                this.navigateToLoginSuccess();
                console.log('You are already logged in');
                return;
            }
            await sessionApis
                .loginWithGoogle(data)
                .then(this.handleLoginResponse)
                // @todo if this fails, don't fetch?
                .catch(this.handleError);
            await this.fetchProfile();
            this.navigateToLoginSuccess();
        };
        this.getTokenAuth = async () => {
            const response = await sessionApis.getTwitterAuthToken();
            return response;
        };
        // shouldEnablePaymentRetrival, shouldEnableAddressRetrival
        this.fetchProfile = async () => {
            const profile = await userContainer
                .fetchUserLiteProfile()
                .then(toUserProfileResponse)
                // @todo inline, but not sure on resolved result
                .then((response) => {
                userContainer.updateFrom(response);
                if (response.responseCode === '401') {
                    clearCookies();
                }
                // this.omniStore.loadUser(response)
                return response;
            })
                .catch(this.handleError);
            /**
             * Session expired check and navigation to the /signin page
             * in the user profile call
             */
            checkSessionExpiredOnMyAccount(profile);
            return Promise.resolve(profile);
        };
        /**
         * @desc this is in parallel, to not block requests
         */
        this.afterRegisterUser = async () => {
            // sessionApis.createList().then(toListResponse)
            // sessionApis.createSaveForLater().then(toListResponse)
            cartContainer
                .viewCart()
                .then(toBagResponse)
                .then((response) => {
                cartContainer.updateFrom(response);
            });
        };
        /**
         * moved out of flow to avoid guarenteed deopt
         */
        this._flow = async () => {
            const isNotLoggedIn = !this.isOrchestrationGuestUser || !this.isGuestUser || !this.isRegisteredUser;
            // const { listStore } = this.omniStore
            // @todo
            // const lastFlow = localStorage.get('last_flow')
            // const now = Date.now()
            // let diff = diffInMinutes(lastSaveTime, now)
            // if (diff < 5) {
            //   return ls.get('flow')
            // }
            // if (isNotLoggedIn) {
            //   console.log('Not Logged In - Creating Guest User')
            //   await this.registerGuestUser().then(this.afterRegisterUser)
            // }
            await when(() => isNotLoggedIn, () => this.registerGuestUser()
            /**
             * @see https://jira.skava.net/browse/SECTEM-5129
             */
            // .then(this.afterRegisterUser)
            );
            // @todo - why is thi not being done?
            // await sessionApis.fetchUserProfile()
            /**
             * @todo ========= needs to heavily cache here
             *
             * @note, async will make it blocking, promise.all may be best
             */
            await when(() => this.isGuestUser || this.isRegisteredUser, () => {
                return sessionApis.fetchList().then(toSyncListResponse);
                // .then(this.omniStore.loadLists)
            });
            await when(() => isString(listContainer.favoriteListId) === true, () => {
                return (sessionApis
                    .fetchListItems(listContainer.favoriteListId)
                    .then(toFavoritesResponse)
                    // .then(this.omniStore.loadFavorites)
                    .catch(this.handleError));
            });
            await when(() => isString(listContainer.saveForLaterListId) === true, () => {
                return (sessionApis
                    .fetchListItems(listContainer.saveForLaterListId)
                    .then(toSaveForLaterResponse)
                    // .then(this.omniStore.loadSaveForLater)
                    .catch(this.handleError));
            });
            // @michael
            // @todo
            // 1. then need to connect this with fixture/graphql
            // 2. and set events to update
            // 3. these could also be set individually per store
            //    or we can use graphql.readQuery but here
            //    we don't have graphql for these calls so
            //    we can also connect oneStorage to check graphql cache
            //      through a single interface (@example cache.has checks graphql)
            //
            // localStorage.set('last_flow', now)
            // localStorage.set('flow', {
            //   viewBag,
            //   storeCredit,
            //   favoritesList,
            // })
        };
        /**
         * @see https://github.com/petkaantonov/bluebird/wiki/Optimization-killers
         * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch
         * @see https://github.com/aretecode/awesome-deopt
         * ^ regarding try catch issues
         */
        this.flow = async () => {
            try {
                await this._flow();
            }
            catch (error) {
                console.error(error);
                throw new Error('API Failed');
            }
        };
    }
    get guestUserCookie() {
        console.log('[COOKIE_CONFIG]', cookieConfig);
        return getCookie(cookieConfig.guest);
    }
    get hasGuestUserCookie() {
        return hasCookie(cookieConfig.guest);
    }
    get hasOrchestrationGuestUserCookie() {
        return hasCookie(cookieConfig.orchestrationGuest);
    }
    /**
     * @@packages @james may want to change this flow because session should not import user?
     */
    get isGuestUser() {
        return this.hasGuestUserCookie || !!userContainer.firstName || !!userContainer.userName;
    }
    get isOrchestrationGuestUser() {
        return this.hasOrchestrationGuestUserCookie;
    }
    get isRegisteredUser() {
        return this.hasUserCookie || !!userContainer.firstName || !!userContainer.userName;
    }
    get hasUserCookie() {
        return hasCookie(cookieConfig.registered);
    }
    get userCookie() {
        return getCookie(cookieConfig.registered);
    }
    // or could force only via props?
    get userName() {
        return this.userCookie || userContainer.userName;
    }
    get isBuyerAdminUser() {
        return getCookie(cookieConfig.buyerAdminNamespace) === 'ROLE_ACCOUNT_BUYER_ADMIN';
    }
    get isBuyerUser() {
        return getCookie(cookieConfig.buyerAdminNamespace) === 'ROLE_BUYER';
    }
    /**
     * @desc much better perf to bind early
     * @see https://mobx.js.org/best/react-performance.html#bind-functions-early
     */
    handleError(error) {
        console.error(error);
    }
    navigateToLoginSuccess(isFromTwitter) {
        const pathParams = appConfig.get('pathParams');
        if (this.isRegisteredUser || isFromTwitter) {
            if (this.navigateBackTo) {
                console.debug('[navigateToLoginSuccess] going back to a previous link');
                oneRouter.update(this.navigateBackTo);
                this.navigateBackTo = '';
            }
            // normal login and register success flow
            else if (this.isBuyerAdminUser) {
                console.debug('[navigateToLoginSuccess] going to my account [b2b]');
                oneRouter.update(pathParams.myaccountDashboard);
            }
            else if (oneRouter.get('pathname') !== '/checkout') {
                console.debug('[navigateToLoginSuccess] going to my account');
                oneRouter.update(pathParams.myaccountLanding || '/myaccount/welcome');
            }
        }
    }
}
SessionContainer.debugName = 'Session';
tslib_1.__decorate([
    computed
], SessionContainer.prototype, "guestUserCookie", null);
tslib_1.__decorate([
    computed
], SessionContainer.prototype, "hasGuestUserCookie", null);
tslib_1.__decorate([
    computed
], SessionContainer.prototype, "hasOrchestrationGuestUserCookie", null);
tslib_1.__decorate([
    computed
], SessionContainer.prototype, "isGuestUser", null);
tslib_1.__decorate([
    computed
], SessionContainer.prototype, "isOrchestrationGuestUser", null);
tslib_1.__decorate([
    computed
], SessionContainer.prototype, "isRegisteredUser", null);
tslib_1.__decorate([
    computed
], SessionContainer.prototype, "hasUserCookie", null);
tslib_1.__decorate([
    computed
], SessionContainer.prototype, "userCookie", null);
tslib_1.__decorate([
    computed
], SessionContainer.prototype, "userName", null);
tslib_1.__decorate([
    computed
], SessionContainer.prototype, "isBuyerAdminUser", null);
tslib_1.__decorate([
    computed
], SessionContainer.prototype, "isBuyerUser", null);
const sessionContainer = new SessionContainer();
export default sessionContainer;
export { sessionContainer, SessionContainer, sessionApis, mapCookiesOnResponse, checkIsSessionExpired, checkSessionExpiredOnMyAccount, };
//# sourceMappingURL=container.js.map