From 8db9b1a2f0c50f8801a8f5220ea3fe233089a554 Mon Sep 17 00:00:00 2001 From: zeppi Date: Thu, 16 Sep 2021 13:55:46 -0400 Subject: [PATCH 1/6] refactor auth --- package.json | 2 +- ui/component/privacyAgreement/index.js | 14 ++-- ui/index.jsx | 32 ++++---- ui/redux/actions/app.js | 14 ++-- ui/redux/actions/user.js | 104 ++++++++++--------------- ui/redux/reducers/user.js | 87 +++++++++++---------- ui/store.js | 16 ++-- ui/util/saved-passwords.js | 26 ++++--- web/src/robots.js | 12 --- yarn.lock | 4 +- 10 files changed, 147 insertions(+), 164 deletions(-) delete mode 100644 web/src/robots.js diff --git a/package.json b/package.json index 03ec42389..f703a11ea 100644 --- a/package.json +++ b/package.json @@ -156,7 +156,7 @@ "json-loader": "^0.5.4", "lbry-format": "https://github.com/lbryio/lbry-format.git", "lbry-redux": "lbryio/lbry-redux#32b578707116d45f5b51b7ab523d200e75668676", - "lbryinc": "lbryio/lbryinc#0b4e41ef90d6347819dd3453f2f9398a5c1b4f36", + "lbryinc": "lbryio/lbryinc#783d7d2d73668a2b96afa9d95d30d29bb580281a", "lint-staged": "^7.0.2", "localforage": "^1.7.1", "lodash-es": "^4.17.14", diff --git a/ui/component/privacyAgreement/index.js b/ui/component/privacyAgreement/index.js index 5a1032a09..551ecd208 100644 --- a/ui/component/privacyAgreement/index.js +++ b/ui/component/privacyAgreement/index.js @@ -1,4 +1,3 @@ -import { DOMAIN } from 'config'; import { connect } from 'react-redux'; import { doSetDaemonSetting } from 'redux/actions/settings'; import { doSetWelcomeVersion, doToggle3PAnalytics, doSignOut } from 'redux/actions/app'; @@ -10,17 +9,16 @@ import { version as appVersion } from 'package.json'; import PrivacyAgreement from './view'; -const select = state => ({ +const select = (state) => ({ authenticated: selectUserVerifiedEmail(state), }); -const perform = dispatch => ({ - setWelcomeVersion: version => dispatch(doSetWelcomeVersion(version || WELCOME_VERSION)), - setShareDataInternal: share => dispatch(doSetDaemonSetting(DAEMON_SETTINGS.SHARE_USAGE_DATA, share)), - setShareDataThirdParty: share => dispatch(doToggle3PAnalytics(share)), +const perform = (dispatch) => ({ + setWelcomeVersion: (version) => dispatch(doSetWelcomeVersion(version || WELCOME_VERSION)), + setShareDataInternal: (share) => dispatch(doSetDaemonSetting(DAEMON_SETTINGS.SHARE_USAGE_DATA, share)), + setShareDataThirdParty: (share) => dispatch(doToggle3PAnalytics(share)), signOut: () => dispatch(doSignOut()), - authenticateIfSharingData: () => - dispatch(doAuthenticate(appVersion, undefined, undefined, true, undefined, undefined, DOMAIN)), + authenticateIfSharingData: () => dispatch(doAuthenticate(appVersion, undefined, undefined, true)), // appVersion, shareData?, shareCallback, callInstall }); export default connect(select, perform)(PrivacyAgreement); diff --git a/ui/index.jsx b/ui/index.jsx index 9b39b6ed7..ece6e260a 100644 --- a/ui/index.jsx +++ b/ui/index.jsx @@ -14,7 +14,7 @@ import * as MODALS from 'constants/modal_types'; import React, { Fragment, useState, useEffect } from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; -import { doDaemonReady, doAutoUpdate, doOpenModal, doHideModal, doToggle3PAnalytics } from 'redux/actions/app'; +import { doLbryReady, doAutoUpdate, doOpenModal, doHideModal, doToggle3PAnalytics } from 'redux/actions/app'; import { Lbry, isURIValid, apiCall } from 'lbry-redux'; import { setSearchApi } from 'redux/actions/search'; import { doSetLanguage, doFetchLanguage, doUpdateIsNightAsync } from 'redux/actions/settings'; @@ -28,12 +28,7 @@ import { formatLbryUrlForWeb, formatInAppUrl } from 'util/url'; import { PersistGate } from 'redux-persist/integration/react'; import analytics from 'analytics'; import { doToast } from 'redux/actions/notifications'; -import { - getAuthToken, - setAuthToken, - doDeprecatedPasswordMigrationMarch2020, - doAuthTokenRefresh, -} from 'util/saved-passwords'; +import { getAuthToken, setAuthToken, doAuthTokenRefresh, deleteAuthToken, getTokens } from 'util/saved-passwords'; import { X_LBRY_AUTH_TOKEN } from 'constants/token'; import { LBRY_WEB_API, DEFAULT_LANGUAGE, LBRY_API_URL, LBRY_WEB_PUBLISH_API } from 'config'; @@ -112,28 +107,33 @@ if (process.env.SEARCH_API_URL) { setSearchApi(process.env.SEARCH_API_URL); } -// Fix to make sure old users' cookies are set to the correct domain -// This can be removed after March 11th, 2021 -// https://github.com/lbryio/lbry-desktop/pull/3830 -doDeprecatedPasswordMigrationMarch2020(); +// TODO KEYCLOAK doAuthTokenRefresh(); // We need to override Lbryio for getting/setting the authToken // We interact with ipcRenderer to get the auth key from a users keyring // We keep a local variable for authToken because `ipcRenderer.send` does not // contain a response, so there is no way to know when it's been set -let authToken; +// let authToken; // deleting Lbryio.setOverride('setAuthToken', (authToken) => { - setAuthToken(authToken); + setAuthToken(authToken); // set the cookie to auth_token= return authToken; }); +Lbryio.setOverride('deleteAuthToken', () => deleteAuthToken()); + +Lbryio.setOverride( + 'getTokens', + () => + new Promise((resolve) => { + resolve(getTokens()); + }) +); Lbryio.setOverride( 'getAuthToken', () => new Promise((resolve) => { - const authTokenToReturn = authToken || getAuthToken(); - resolve(authTokenToReturn); + resolve(getAuthToken()); }) ); @@ -266,7 +266,7 @@ function AppWrapper() { app.store.dispatch(doFetchLanguage(DEFAULT_LANGUAGE)); } app.store.dispatch(doUpdateIsNightAsync()); - app.store.dispatch(doDaemonReady()); + app.store.dispatch(doLbryReady()); // app.store.dispatch(doBlackListedOutpointsSubscribe()); app.store.dispatch(doFilteredOutpointsSubscribe()); diff --git a/ui/redux/actions/app.js b/ui/redux/actions/app.js index 67a00c4a0..d2229e82a 100644 --- a/ui/redux/actions/app.js +++ b/ui/redux/actions/app.js @@ -6,7 +6,7 @@ import { ipcRenderer, remote } from 'electron'; import path from 'path'; import * as ACTIONS from 'constants/action_types'; import * as MODALS from 'constants/modal_types'; -import { DOMAIN, SIMPLE_SITE } from 'config'; +import { SIMPLE_SITE } from 'config'; import { Lbry, doBalanceSubscribe, @@ -353,18 +353,19 @@ export function doAlertWaitingForSync() { }; } -export function doDaemonReady() { +export function doLbryReady() { return (dispatch, getState) => { const state = getState(); // TODO: call doFetchDaemonSettings, then get usage data, and call doAuthenticate once they are loaded into the store const shareUsageData = IS_WEB || window.localStorage.getItem(SHARE_INTERNAL) === 'true'; - + /** + * doAuthenticate -> Lbryio.authenticate, then update redux with auth token. + * authenticate: Use auth token to get or create user.getCurrentUser. return user + */ dispatch( doAuthenticate( appVersion, - undefined, - undefined, shareUsageData, (status) => { const trendingAlgorithm = @@ -377,8 +378,7 @@ export function doDaemonReady() { analytics.trendingAlgorithmEvent(trendingAlgorithm); } }, - undefined, - DOMAIN + undefined ) ); dispatch({ type: ACTIONS.DAEMON_READY }); diff --git a/ui/redux/actions/user.js b/ui/redux/actions/user.js index 5738eb3c0..088633a7f 100644 --- a/ui/redux/actions/user.js +++ b/ui/redux/actions/user.js @@ -50,11 +50,8 @@ export function doFetchInviteStatus(shouldCallRewardList = true) { }; } -export function doInstallNew(appVersion, os = null, firebaseToken = null, callbackForUsersWhoAreSharingData, domain) { +export function doInstallNew(appVersion, callbackForUsersWhoAreSharingData, domain) { const payload = { app_version: appVersion, domain }; - if (firebaseToken) { - payload.firebase_token = firebaseToken; - } Lbry.status().then((status) => { payload.app_id = @@ -64,7 +61,7 @@ export function doInstallNew(appVersion, os = null, firebaseToken = null, callba payload.node_id = status.lbry_id; Lbry.version().then((version) => { payload.daemon_version = version.lbrynet_version; - payload.operating_system = os || version.os_system; + payload.operating_system = version.os_system; payload.platform = version.platform; Lbryio.call('install', 'new', payload); @@ -75,33 +72,9 @@ export function doInstallNew(appVersion, os = null, firebaseToken = null, callba }); } -export function doInstallNewWithParams( - appVersion, - installationId, - nodeId, - lbrynetVersion, - os, - platform, - firebaseToken = null -) { - return () => { - const payload = { app_version: appVersion }; - if (firebaseToken) { - payload.firebase_token = firebaseToken; - } - - payload.app_id = installationId; - payload.node_id = nodeId; - payload.daemon_version = lbrynetVersion; - payload.operating_system = os; - payload.platform = platform; - Lbryio.call('install', 'new', payload); - }; -} - function checkAuthBusy() { let time = Date.now(); - return new Promise(function(resolve, reject) { + return new Promise(function (resolve, reject) { (function waitForAuth() { try { sessionStorage.setItem('test', 'available'); @@ -131,48 +104,57 @@ function checkAuthBusy() { } // TODO: Call doInstallNew separately so we don't have to pass appVersion and os_system params? +/** + * + * @param appVersion + * @param shareUsageData + * @param callbackForUsersWhoAreSharingData + * @param callInstall + * @returns {Function} + * + * Does Lbryio.authenticate, i.e. call Authenticate() then update redux with auth token. + * Authenticate does getAuthToken then getCurrentUser, and if !user, call userNew and return the user + * telling redux the auth token is probably dumb. we will + * keycloak = useKeycloak(), keycloak.token whenever we want that + * + */ export function doAuthenticate( appVersion, - os = null, - firebaseToken = null, shareUsageData = true, callbackForUsersWhoAreSharingData, - callInstall = true, - domain = null + callInstall = true ) { - return (dispatch) => { + return async (dispatch) => { dispatch({ type: ACTIONS.AUTHENTICATION_STARTED, }); - checkAuthBusy() - .then(() => { - return Lbryio.authenticate(DOMAIN, getDefaultLanguage()); - }) - .then((user) => { - if (sessionStorageAvailable) window.sessionStorage.removeItem(AUTH_IN_PROGRESS); - Lbryio.getAuthToken().then((token) => { - dispatch({ - type: ACTIONS.AUTHENTICATION_SUCCESS, - data: { user, accessToken: token }, - }); - - if (shareUsageData) { - dispatch(doRewardList()); - dispatch(doFetchInviteStatus(false)); - if (callInstall) { - doInstallNew(appVersion, os, firebaseToken, callbackForUsersWhoAreSharingData, domain); - } - } - }); - }) - .catch((error) => { - if (sessionStorageAvailable) window.sessionStorage.removeItem(AUTH_IN_PROGRESS); - + try { + await checkAuthBusy(); + const user = await Lbryio.authenticate(DOMAIN, getDefaultLanguage()); + console.log('USER', user); + if (sessionStorageAvailable) window.sessionStorage.removeItem(AUTH_IN_PROGRESS); + // put this back , accessToken: tokens.access_token + Lbryio.getTokens().then((tokens) => { dispatch({ - type: ACTIONS.AUTHENTICATION_FAILURE, - data: { error }, + type: ACTIONS.AUTHENTICATION_SUCCESS, + data: { user, accessToken: tokens.auth_token }, // rename 'accessToken' = auth_token }); + if (shareUsageData) { + dispatch(doRewardList()); + dispatch(doFetchInviteStatus(false)); + if (callInstall) { + doInstallNew(appVersion, callbackForUsersWhoAreSharingData, DOMAIN); + } + } }); + } catch (error) { + if (sessionStorageAvailable) window.sessionStorage.removeItem(AUTH_IN_PROGRESS); + + dispatch({ + type: ACTIONS.AUTHENTICATION_FAILURE, + data: { error }, + }); + } }; } diff --git a/ui/redux/reducers/user.js b/ui/redux/reducers/user.js index d31078f1f..685bed5c8 100644 --- a/ui/redux/reducers/user.js +++ b/ui/redux/reducers/user.js @@ -24,37 +24,44 @@ const defaultState = { invitees: undefined, referralLink: undefined, referralCode: undefined, - user: undefined, - accessToken: undefined, + user: { has_verified_email: false }, + accessToken: undefined, // rename this youtubeChannelImportPending: false, youtubeChannelImportErrorMessage: '', referrerSetIsPending: false, referrerSetError: '', }; -reducers[ACTIONS.AUTHENTICATION_STARTED] = state => +// does this do anything with user? +reducers[ACTIONS.AUTHENTICATION_STARTED] = (state) => Object.assign({}, state, { authenticationIsPending: true, userIsPending: true, + // distinguish accessToken from authToken accessToken: defaultState.accessToken, }); -reducers[ACTIONS.AUTHENTICATION_SUCCESS] = (state, action) => +reducers[ACTIONS.AUTHENTICATION_SUCCESS] = (state, action) => { + const newUserState = Object.assign({}, state, { + authenticationIsPending: false, + userIsPending: false, + }); + if (action.data && action.data.user) { + newUserState.user = action.data.user; + } + if (action.data && action.data.accessToken) { + newUserState.accessToken = action.data.accessToken; + } + return newUserState; +}; + +reducers[ACTIONS.AUTHENTICATION_FAILURE] = (state) => Object.assign({}, state, { authenticationIsPending: false, userIsPending: false, - accessToken: action.data.accessToken, - user: action.data.user, }); -reducers[ACTIONS.AUTHENTICATION_FAILURE] = state => - Object.assign({}, state, { - authenticationIsPending: false, - userIsPending: false, - user: null, - }); - -reducers[ACTIONS.USER_FETCH_STARTED] = state => +reducers[ACTIONS.USER_FETCH_STARTED] = (state) => Object.assign({}, state, { userIsPending: true, }); @@ -66,7 +73,7 @@ reducers[ACTIONS.USER_FETCH_SUCCESS] = (state, action) => emailToVerify: action.data.user.has_verified_email ? null : state.emailToVerify, }); -reducers[ACTIONS.USER_FETCH_FAILURE] = state => +reducers[ACTIONS.USER_FETCH_FAILURE] = (state) => Object.assign({}, state, { userIsPending: true, user: null, @@ -88,7 +95,7 @@ reducers[ACTIONS.USER_PHONE_NEW_SUCCESS] = (state, action) => phoneNewIsPending: false, }); -reducers[ACTIONS.USER_PHONE_RESET] = state => +reducers[ACTIONS.USER_PHONE_RESET] = (state) => Object.assign({}, state, { phoneToVerify: null, }); @@ -99,7 +106,7 @@ reducers[ACTIONS.USER_PHONE_NEW_FAILURE] = (state, action) => phoneNewErrorMessage: action.data.error, }); -reducers[ACTIONS.USER_PHONE_VERIFY_STARTED] = state => +reducers[ACTIONS.USER_PHONE_VERIFY_STARTED] = (state) => Object.assign({}, state, { phoneVerifyIsPending: true, phoneVerifyErrorMessage: '', @@ -118,7 +125,7 @@ reducers[ACTIONS.USER_PHONE_VERIFY_FAILURE] = (state, action) => phoneVerifyErrorMessage: action.data.error, }); -reducers[ACTIONS.USER_EMAIL_NEW_STARTED] = state => +reducers[ACTIONS.USER_EMAIL_NEW_STARTED] = (state) => Object.assign({}, state, { emailNewIsPending: true, emailNewErrorMessage: '', @@ -136,12 +143,12 @@ reducers[ACTIONS.USER_EMAIL_NEW_SUCCESS] = (state, action) => { }); }; -reducers[ACTIONS.USER_EMAIL_NEW_EXISTS] = state => +reducers[ACTIONS.USER_EMAIL_NEW_EXISTS] = (state) => Object.assign({}, state, { emailAlreadyExists: true, }); -reducers[ACTIONS.USER_EMAIL_NEW_DOES_NOT_EXIST] = state => +reducers[ACTIONS.USER_EMAIL_NEW_DOES_NOT_EXIST] = (state) => Object.assign({}, state, { emailDoesNotExist: true, }); @@ -152,7 +159,7 @@ reducers[ACTIONS.USER_EMAIL_NEW_FAILURE] = (state, action) => emailNewErrorMessage: action.data.error, }); -reducers[ACTIONS.USER_EMAIL_NEW_CLEAR_ENTRY] = state => { +reducers[ACTIONS.USER_EMAIL_NEW_CLEAR_ENTRY] = (state) => { const newUser = { ...state.user }; delete newUser.primary_email; @@ -166,7 +173,7 @@ reducers[ACTIONS.USER_EMAIL_NEW_CLEAR_ENTRY] = state => { }); }; -reducers[ACTIONS.USER_PASSWORD_SET_CLEAR] = state => +reducers[ACTIONS.USER_PASSWORD_SET_CLEAR] = (state) => Object.assign({}, state, { passwordResetSuccess: false, passwordResetPending: false, @@ -175,7 +182,7 @@ reducers[ACTIONS.USER_PASSWORD_SET_CLEAR] = state => passwordSetSuccess: false, }); -reducers[ACTIONS.USER_EMAIL_VERIFY_STARTED] = state => +reducers[ACTIONS.USER_EMAIL_VERIFY_STARTED] = (state) => Object.assign({}, state, { emailVerifyIsPending: true, emailVerifyErrorMessage: '', @@ -202,7 +209,7 @@ reducers[ACTIONS.USER_EMAIL_VERIFY_SET] = (state, action) => emailToVerify: action.data.email, }); -reducers[ACTIONS.USER_IDENTITY_VERIFY_STARTED] = state => +reducers[ACTIONS.USER_IDENTITY_VERIFY_STARTED] = (state) => Object.assign({}, state, { identityVerifyIsPending: true, identityVerifyErrorMessage: '', @@ -229,7 +236,7 @@ reducers[ACTIONS.FETCH_ACCESS_TOKEN_SUCCESS] = (state, action) => { }); }; -reducers[ACTIONS.USER_INVITE_STATUS_FETCH_STARTED] = state => +reducers[ACTIONS.USER_INVITE_STATUS_FETCH_STARTED] = (state) => Object.assign({}, state, { inviteStatusIsPending: true, }); @@ -243,13 +250,13 @@ reducers[ACTIONS.USER_INVITE_STATUS_FETCH_SUCCESS] = (state, action) => referralCode: action.data.referralCode, }); -reducers[ACTIONS.USER_INVITE_NEW_STARTED] = state => +reducers[ACTIONS.USER_INVITE_NEW_STARTED] = (state) => Object.assign({}, state, { inviteNewIsPending: true, inviteNewErrorMessage: '', }); -reducers[ACTIONS.USER_INVITE_NEW_SUCCESS] = state => +reducers[ACTIONS.USER_INVITE_NEW_SUCCESS] = (state) => Object.assign({}, state, { inviteNewIsPending: false, inviteNewErrorMessage: '', @@ -261,14 +268,14 @@ reducers[ACTIONS.USER_INVITE_NEW_FAILURE] = (state, action) => inviteNewErrorMessage: action.data.error.message, }); -reducers[ACTIONS.USER_INVITE_STATUS_FETCH_FAILURE] = state => +reducers[ACTIONS.USER_INVITE_STATUS_FETCH_FAILURE] = (state) => Object.assign({}, state, { inviteStatusIsPending: false, invitesRemaining: null, invitees: null, }); -reducers[ACTIONS.USER_YOUTUBE_IMPORT_STARTED] = state => +reducers[ACTIONS.USER_YOUTUBE_IMPORT_STARTED] = (state) => Object.assign({}, state, { youtubeChannelImportPending: true, youtubeChannelImportErrorMessage: '', @@ -293,28 +300,28 @@ reducers[ACTIONS.USER_YOUTUBE_IMPORT_FAILURE] = (state, action) => youtubeChannelImportErrorMessage: action.data, }); -reducers[ACTIONS.USER_EMAIL_VERIFY_RETRY_STARTED] = state => +reducers[ACTIONS.USER_EMAIL_VERIFY_RETRY_STARTED] = (state) => Object.assign({}, state, { resendingVerificationEmail: true, }); -reducers[ACTIONS.USER_EMAIL_VERIFY_RETRY_SUCCESS] = state => +reducers[ACTIONS.USER_EMAIL_VERIFY_RETRY_SUCCESS] = (state) => Object.assign({}, state, { resendingVerificationEmail: false, }); -reducers[ACTIONS.USER_EMAIL_VERIFY_RETRY_FAILURE] = state => +reducers[ACTIONS.USER_EMAIL_VERIFY_RETRY_FAILURE] = (state) => Object.assign({}, state, { resendingVerificationEmail: false, }); -reducers[ACTIONS.USER_SET_REFERRER_STARTED] = state => +reducers[ACTIONS.USER_SET_REFERRER_STARTED] = (state) => Object.assign({}, state, { referrerSetIsPending: true, referrerSetError: defaultState.referrerSetError, }); -reducers[ACTIONS.USER_SET_REFERRER_SUCCESS] = state => +reducers[ACTIONS.USER_SET_REFERRER_SUCCESS] = (state) => Object.assign({}, state, { referrerSetIsPending: false, referrerSetError: defaultState.referrerSetError, @@ -326,25 +333,25 @@ reducers[ACTIONS.USER_SET_REFERRER_FAILURE] = (state, action) => referrerSetError: action.data.error.message, }); -reducers[ACTIONS.USER_SET_REFERRER_RESET] = state => +reducers[ACTIONS.USER_SET_REFERRER_RESET] = (state) => Object.assign({}, state, { referrerSetIsPending: false, referrerSetError: defaultState.referrerSetError, }); -reducers[ACTIONS.USER_PASSWORD_EXISTS] = state => +reducers[ACTIONS.USER_PASSWORD_EXISTS] = (state) => Object.assign({}, state, { passwordExistsForUser: true, }); -reducers[ACTIONS.USER_PASSWORD_RESET_STARTED] = state => +reducers[ACTIONS.USER_PASSWORD_RESET_STARTED] = (state) => Object.assign({}, state, { passwordResetPending: true, passwordResetSuccess: defaultState.passwordResetSuccess, passwordResetError: null, }); -reducers[ACTIONS.USER_PASSWORD_RESET_SUCCESS] = state => +reducers[ACTIONS.USER_PASSWORD_RESET_SUCCESS] = (state) => Object.assign({}, state, { passwordResetPending: false, passwordResetSuccess: true, @@ -356,13 +363,13 @@ reducers[ACTIONS.USER_PASSWORD_RESET_FAILURE] = (state, action) => passwordResetError: action.data.error, }); -reducers[ACTIONS.USER_PASSWORD_SET_STARTED] = state => +reducers[ACTIONS.USER_PASSWORD_SET_STARTED] = (state) => Object.assign({}, state, { passwordSetPending: true, passwordSetSuccess: defaultState.passwordSetSuccess, }); -reducers[ACTIONS.USER_PASSWORD_SET_SUCCESS] = state => +reducers[ACTIONS.USER_PASSWORD_SET_SUCCESS] = (state) => Object.assign({}, state, { passwordSetPending: false, passwordSetSuccess: true, diff --git a/ui/store.js b/ui/store.js index c7f415253..d728cfd12 100644 --- a/ui/store.js +++ b/ui/store.js @@ -11,7 +11,7 @@ import { routerMiddleware } from 'connected-react-router'; import createRootReducer from './reducers'; import { Lbry, buildSharedStateMiddleware, ACTIONS as LBRY_REDUX_ACTIONS } from 'lbry-redux'; import { doSyncLoop } from 'redux/actions/sync'; -import { getAuthToken } from 'util/saved-passwords'; +import { getTokens } from 'util/saved-passwords'; import { generateInitialUrl } from 'util/url'; import { X_LBRY_AUTH_TOKEN } from 'constants/token'; @@ -189,12 +189,14 @@ const sharedStateCb = ({ dispatch, getState }) => { const populateAuthTokenHeader = () => { return (next) => (action) => { - if ( - (action.type === ACTIONS.USER_FETCH_SUCCESS || action.type === ACTIONS.AUTHENTICATION_SUCCESS) && - action.data.user.has_verified_email === true - ) { - const authToken = getAuthToken(); - Lbry.setApiHeader(X_LBRY_AUTH_TOKEN, authToken); + if (action.type === ACTIONS.USER_FETCH_SUCCESS || action.type === ACTIONS.AUTHENTICATION_SUCCESS) { + if (action.data) { + } + const tokens = getTokens(); + // if (tokens.access_token) { + // Lbry.setApiHeader('Authorization', 'Bearer ' + tokens.access_token); + // } + Lbry.setApiHeader(X_LBRY_AUTH_TOKEN, tokens.auth_token); } return next(action); diff --git a/ui/util/saved-passwords.js b/ui/util/saved-passwords.js index db71bdd8d..ee21e99cf 100644 --- a/ui/util/saved-passwords.js +++ b/ui/util/saved-passwords.js @@ -1,4 +1,4 @@ -const { DOMAIN } = require('../../config.js'); +const { DOMAIN } = require('config.js'); const AUTH_TOKEN = 'auth_token'; const SAVED_PASSWORD = 'saved_password'; const DEPRECATED_SAVED_PASSWORD = 'saved-password'; @@ -59,7 +59,7 @@ function deleteCookie(name) { } function setSavedPassword(value, saveToDisk) { - return new Promise(resolve => { + return new Promise((resolve) => { const password = value === undefined || value === null ? '' : value; sessionPassword = password; @@ -74,17 +74,17 @@ function setSavedPassword(value, saveToDisk) { } function getSavedPassword() { - return new Promise(resolve => { + return new Promise((resolve) => { if (sessionPassword) { resolve(sessionPassword); } - return getPasswordFromCookie().then(p => resolve(p)); + return getPasswordFromCookie().then((p) => resolve(p)); }); } function getPasswordFromCookie() { - return new Promise(resolve => { + return new Promise((resolve) => { let password; password = getCookie(SAVED_PASSWORD); resolve(password); @@ -92,7 +92,7 @@ function getPasswordFromCookie() { } function deleteSavedPassword() { - return new Promise(resolve => { + return new Promise((resolve) => { deleteCookie(SAVED_PASSWORD); resolve(); }); @@ -102,19 +102,24 @@ function getAuthToken() { return getCookie(AUTH_TOKEN); } +// will take oidc token getter +function getTokens() { + return { auth_token: getAuthToken(), access_token: null }; +} + function setAuthToken(value) { return setCookie(AUTH_TOKEN, value, 365); } function deleteAuthToken() { - return new Promise(resolve => { + return new Promise((resolve) => { deleteCookie(AUTH_TOKEN); resolve(); }); } function doSignOutCleanup() { - return new Promise(resolve => { + return new Promise((resolve) => { deleteAuthToken(); deleteSavedPassword(); resolve(); @@ -122,10 +127,10 @@ function doSignOutCleanup() { } function doAuthTokenRefresh() { - const authToken = getAuthToken(); + const { auth_token: authToken } = getAuthToken(); if (authToken) { deleteAuthToken(); - setAuthToken(authToken); + setCookie(AUTH_TOKEN, authToken, 365); } } @@ -147,6 +152,7 @@ module.exports = { deleteSavedPassword, getAuthToken, setAuthToken, + getTokens, deleteAuthToken, doSignOutCleanup, doAuthTokenRefresh, diff --git a/web/src/robots.js b/web/src/robots.js deleted file mode 100644 index c76140386..000000000 --- a/web/src/robots.js +++ /dev/null @@ -1,12 +0,0 @@ -const fs = require('fs'); -const path = require('path'); - -let robots; -async function getRobots(ctx) { - if (!robots) { - robots = fs.readFileSync(path.join(__dirname, '/../dist/public/robots.txt'), 'utf8'); - } - return robots; -} - -module.exports = { getRobots }; diff --git a/yarn.lock b/yarn.lock index 96aee291f..f20270aab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10148,9 +10148,9 @@ lbry-redux@lbryio/lbry-redux#32b578707116d45f5b51b7ab523d200e75668676: reselect "^3.0.0" uuid "^8.3.1" -lbryinc@lbryio/lbryinc#0b4e41ef90d6347819dd3453f2f9398a5c1b4f36: +lbryinc@lbryio/lbryinc#783d7d2d73668a2b96afa9d95d30d29bb580281a: version "0.0.1" - resolved "https://codeload.github.com/lbryio/lbryinc/tar.gz/0b4e41ef90d6347819dd3453f2f9398a5c1b4f36" + resolved "https://codeload.github.com/lbryio/lbryinc/tar.gz/783d7d2d73668a2b96afa9d95d30d29bb580281a" dependencies: reselect "^3.0.0" -- 2.45.2 From 80e9de991b5c5ef1f9d5c8f0a3204ca6a342c524 Mon Sep 17 00:00:00 2001 From: zeppi Date: Thu, 16 Sep 2021 14:33:52 -0400 Subject: [PATCH 2/6] bugfix --- ui/index.jsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ui/index.jsx b/ui/index.jsx index ece6e260a..a98a93e8a 100644 --- a/ui/index.jsx +++ b/ui/index.jsx @@ -108,7 +108,11 @@ if (process.env.SEARCH_API_URL) { } // TODO KEYCLOAK -doAuthTokenRefresh(); +getTokens.then(tokens => { + if (tokens.auth_token) { + doAuthTokenRefresh(); + } +}); // We need to override Lbryio for getting/setting the authToken // We interact with ipcRenderer to get the auth key from a users keyring -- 2.45.2 From 7f9c51b143db58b90ed4b55b1b2decc0f8b894ab Mon Sep 17 00:00:00 2001 From: zeppi Date: Thu, 16 Sep 2021 14:59:54 -0400 Subject: [PATCH 3/6] bugfix --- ui/index.jsx | 8 +++----- ui/redux/actions/user.js | 6 +++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/ui/index.jsx b/ui/index.jsx index a98a93e8a..1a2ccbed4 100644 --- a/ui/index.jsx +++ b/ui/index.jsx @@ -108,11 +108,9 @@ if (process.env.SEARCH_API_URL) { } // TODO KEYCLOAK -getTokens.then(tokens => { - if (tokens.auth_token) { - doAuthTokenRefresh(); - } -}); +if (getTokens().auth_token) { + doAuthTokenRefresh(); +} // We need to override Lbryio for getting/setting the authToken // We interact with ipcRenderer to get the auth key from a users keyring diff --git a/ui/redux/actions/user.js b/ui/redux/actions/user.js index 088633a7f..2d7f70628 100644 --- a/ui/redux/actions/user.js +++ b/ui/redux/actions/user.js @@ -130,7 +130,7 @@ export function doAuthenticate( }); try { await checkAuthBusy(); - const user = await Lbryio.authenticate(DOMAIN, getDefaultLanguage()); + const user = await Lbryio.fetchUser(DOMAIN, getDefaultLanguage()); console.log('USER', user); if (sessionStorageAvailable) window.sessionStorage.removeItem(AUTH_IN_PROGRESS); // put this back , accessToken: tokens.access_token @@ -165,7 +165,7 @@ export function doUserFetch() { type: ACTIONS.USER_FETCH_STARTED, }); - Lbryio.getCurrentUser() + Lbryio.fetchCurrentUser() .then((user) => { dispatch({ type: ACTIONS.USER_FETCH_SUCCESS, @@ -186,7 +186,7 @@ export function doUserFetch() { export function doUserCheckEmailVerified() { // This will happen in the background so we don't need loading booleans return (dispatch) => { - Lbryio.getCurrentUser().then((user) => { + Lbryio.fetchCurrentUser().then((user) => { if (user.has_verified_email) { dispatch(doRewardList()); -- 2.45.2 From 6f27525ec21fe2afab3e877f447cd8c434c00c74 Mon Sep 17 00:00:00 2001 From: zeppi Date: Thu, 16 Sep 2021 16:01:54 -0400 Subject: [PATCH 4/6] cleanup --- package.json | 2 +- ui/index.jsx | 3 +-- ui/redux/actions/user.js | 6 ++---- yarn.lock | 4 ++-- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index f703a11ea..9d47fb283 100644 --- a/package.json +++ b/package.json @@ -156,7 +156,7 @@ "json-loader": "^0.5.4", "lbry-format": "https://github.com/lbryio/lbry-format.git", "lbry-redux": "lbryio/lbry-redux#32b578707116d45f5b51b7ab523d200e75668676", - "lbryinc": "lbryio/lbryinc#783d7d2d73668a2b96afa9d95d30d29bb580281a", + "lbryinc": "lbryio/lbryinc#22906b5857863b0ff393e07f92846cb09f48366b", "lint-staged": "^7.0.2", "localforage": "^1.7.1", "lodash-es": "^4.17.14", diff --git a/ui/index.jsx b/ui/index.jsx index 1a2ccbed4..97df008b4 100644 --- a/ui/index.jsx +++ b/ui/index.jsx @@ -116,7 +116,6 @@ if (getTokens().auth_token) { // We interact with ipcRenderer to get the auth key from a users keyring // We keep a local variable for authToken because `ipcRenderer.send` does not // contain a response, so there is no way to know when it's been set -// let authToken; // deleting Lbryio.setOverride('setAuthToken', (authToken) => { setAuthToken(authToken); // set the cookie to auth_token= return authToken; @@ -268,7 +267,7 @@ function AppWrapper() { app.store.dispatch(doFetchLanguage(DEFAULT_LANGUAGE)); } app.store.dispatch(doUpdateIsNightAsync()); - app.store.dispatch(doLbryReady()); // + app.store.dispatch(doLbryReady()); // get tokens, users, startup stuff app.store.dispatch(doBlackListedOutpointsSubscribe()); app.store.dispatch(doFilteredOutpointsSubscribe()); diff --git a/ui/redux/actions/user.js b/ui/redux/actions/user.js index 2d7f70628..9bb284e17 100644 --- a/ui/redux/actions/user.js +++ b/ui/redux/actions/user.js @@ -112,10 +112,8 @@ function checkAuthBusy() { * @param callInstall * @returns {Function} * - * Does Lbryio.authenticate, i.e. call Authenticate() then update redux with auth token. - * Authenticate does getAuthToken then getCurrentUser, and if !user, call userNew and return the user - * telling redux the auth token is probably dumb. we will - * keycloak = useKeycloak(), keycloak.token whenever we want that + * Lbryio.fetchUser: + * getTokens then getCurrentUser, and if !user, call userNew and return the user * */ export function doAuthenticate( diff --git a/yarn.lock b/yarn.lock index f20270aab..191d6c2e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10148,9 +10148,9 @@ lbry-redux@lbryio/lbry-redux#32b578707116d45f5b51b7ab523d200e75668676: reselect "^3.0.0" uuid "^8.3.1" -lbryinc@lbryio/lbryinc#783d7d2d73668a2b96afa9d95d30d29bb580281a: +lbryinc@lbryio/lbryinc#22906b5857863b0ff393e07f92846cb09f48366b: version "0.0.1" - resolved "https://codeload.github.com/lbryio/lbryinc/tar.gz/783d7d2d73668a2b96afa9d95d30d29bb580281a" + resolved "https://codeload.github.com/lbryio/lbryinc/tar.gz/22906b5857863b0ff393e07f92846cb09f48366b" dependencies: reselect "^3.0.0" -- 2.45.2 From b5383a312e9ce35a25bc31113279fa85760ff699 Mon Sep 17 00:00:00 2001 From: zeppi Date: Tue, 21 Sep 2021 15:12:52 -0400 Subject: [PATCH 5/6] better user errors --- ui/redux/actions/app.js | 5 +---- ui/redux/actions/user.js | 30 +++++++++++++++++------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/ui/redux/actions/app.js b/ui/redux/actions/app.js index d2229e82a..8a4a15446 100644 --- a/ui/redux/actions/app.js +++ b/ui/redux/actions/app.js @@ -359,10 +359,7 @@ export function doLbryReady() { // TODO: call doFetchDaemonSettings, then get usage data, and call doAuthenticate once they are loaded into the store const shareUsageData = IS_WEB || window.localStorage.getItem(SHARE_INTERNAL) === 'true'; - /** - * doAuthenticate -> Lbryio.authenticate, then update redux with auth token. - * authenticate: Use auth token to get or create user.getCurrentUser. return user - */ + dispatch( doAuthenticate( appVersion, diff --git a/ui/redux/actions/user.js b/ui/redux/actions/user.js index 9bb284e17..0b32ee28c 100644 --- a/ui/redux/actions/user.js +++ b/ui/redux/actions/user.js @@ -131,20 +131,24 @@ export function doAuthenticate( const user = await Lbryio.fetchUser(DOMAIN, getDefaultLanguage()); console.log('USER', user); if (sessionStorageAvailable) window.sessionStorage.removeItem(AUTH_IN_PROGRESS); - // put this back , accessToken: tokens.access_token - Lbryio.getTokens().then((tokens) => { - dispatch({ - type: ACTIONS.AUTHENTICATION_SUCCESS, - data: { user, accessToken: tokens.auth_token }, // rename 'accessToken' = auth_token - }); - if (shareUsageData) { - dispatch(doRewardList()); - dispatch(doFetchInviteStatus(false)); - if (callInstall) { - doInstallNew(appVersion, callbackForUsersWhoAreSharingData, DOMAIN); + // put this back: accessToken: tokens.access_token + if (user.error) { + throw new Error(user.error.message); + } else { + Lbryio.getTokens().then((tokens) => { + dispatch({ + type: ACTIONS.AUTHENTICATION_SUCCESS, + data: { user, accessToken: tokens.auth_token }, // rename 'accessToken' = authToken + }); + if (shareUsageData) { + dispatch(doRewardList()); + dispatch(doFetchInviteStatus(false)); + if (callInstall) { + doInstallNew(appVersion, callbackForUsersWhoAreSharingData, DOMAIN); + } } - } - }); + }); + } } catch (error) { if (sessionStorageAvailable) window.sessionStorage.removeItem(AUTH_IN_PROGRESS); -- 2.45.2 From 7b8189b77d840f007cdc3f491570e5ef35f21baf Mon Sep 17 00:00:00 2001 From: zeppi Date: Tue, 21 Sep 2021 15:20:04 -0400 Subject: [PATCH 6/6] bump --- package.json | 2 +- yarn.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 9d47fb283..9a1839a43 100644 --- a/package.json +++ b/package.json @@ -156,7 +156,7 @@ "json-loader": "^0.5.4", "lbry-format": "https://github.com/lbryio/lbry-format.git", "lbry-redux": "lbryio/lbry-redux#32b578707116d45f5b51b7ab523d200e75668676", - "lbryinc": "lbryio/lbryinc#22906b5857863b0ff393e07f92846cb09f48366b", + "lbryinc": "lbryio/lbryinc#c9ced4f226e06f4f188cb8dc31b561e1c27c5266", "lint-staged": "^7.0.2", "localforage": "^1.7.1", "lodash-es": "^4.17.14", diff --git a/yarn.lock b/yarn.lock index 191d6c2e7..f7bfe05db 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10148,9 +10148,9 @@ lbry-redux@lbryio/lbry-redux#32b578707116d45f5b51b7ab523d200e75668676: reselect "^3.0.0" uuid "^8.3.1" -lbryinc@lbryio/lbryinc#22906b5857863b0ff393e07f92846cb09f48366b: +lbryinc@lbryio/lbryinc#c9ced4f226e06f4f188cb8dc31b561e1c27c5266: version "0.0.1" - resolved "https://codeload.github.com/lbryio/lbryinc/tar.gz/22906b5857863b0ff393e07f92846cb09f48366b" + resolved "https://codeload.github.com/lbryio/lbryinc/tar.gz/c9ced4f226e06f4f188cb8dc31b561e1c27c5266" dependencies: reselect "^3.0.0" -- 2.45.2