diff --git a/app/soapbox/actions/auth.js b/app/soapbox/actions/auth.js index 5274a98cf..dde684f77 100644 --- a/app/soapbox/actions/auth.js +++ b/app/soapbox/actions/auth.js @@ -213,6 +213,34 @@ export function logIn(intl, username, password) { }; } +export function ethereumLogin() { + return (dispatch, getState) => { + const { ethereum } = window; + const loginMessage = getState().getIn(['instance', 'login_message']); + + return ethereum.request({ method: 'eth_requestAccounts' }).then(walletAddresses => { + const [walletAddress] = walletAddresses; + + return ethereum.request({ method: 'personal_sign', params: [loginMessage, walletAddress] }).then(signature => { + const params = { + grant_type: 'ethereum', + wallet_address: walletAddress.toLowerCase(), + password: signature, + redirect_uri: 'urn:ietf:wg:oauth:2.0:oob', + scope: getScopes(getState()), + }; + + // Note: skips app creation + // TODO: add to quirks.js for Mitra + return dispatch(obtainOAuthToken(params)).then(token => { + dispatch(authLoggedIn(token)); + return dispatch(verifyCredentials(token.access_token)); + }); + }); + }); + }; +} + export function logOut(intl) { return (dispatch, getState) => { const state = getState(); diff --git a/app/soapbox/features/auth_login/components/login_form.js b/app/soapbox/features/auth_login/components/login_form.js index 62b80f0af..549ebb338 100644 --- a/app/soapbox/features/auth_login/components/login_form.js +++ b/app/soapbox/features/auth_login/components/login_form.js @@ -15,11 +15,10 @@ const messages = defineMessages({ const mapStateToProps = state => { const instance = state.get('instance'); - const features = getFeatures(instance); return { baseURL: getBaseURL(state), - hasResetPasswordAPI: features.resetPasswordAPI, + features: getFeatures(instance), }; }; @@ -28,7 +27,7 @@ export default @connect(mapStateToProps) class LoginForm extends ImmutablePureComponent { render() { - const { intl, isLoading, handleSubmit, baseURL, hasResetPasswordAPI } = this.props; + const { intl, isLoading, handleSubmit, baseURL, features } = this.props; return (
@@ -57,12 +56,8 @@ class LoginForm extends ImmutablePureComponent { autoCapitalize='off' required /> - {/*
- -
*/}

- {hasResetPasswordAPI ? ( + {features.resetPasswordAPI ? ( diff --git a/app/soapbox/features/auth_login/components/login_page.js b/app/soapbox/features/auth_login/components/login_page.js index ca16c2a81..d6de2ca3d 100644 --- a/app/soapbox/features/auth_login/components/login_page.js +++ b/app/soapbox/features/auth_login/components/login_page.js @@ -4,18 +4,25 @@ import { injectIntl } from 'react-intl'; import { connect } from 'react-redux'; import { Redirect } from 'react-router-dom'; +import { ethereumLogin } from 'soapbox/actions/auth'; import { logIn, verifyCredentials, switchAccount } from 'soapbox/actions/auth'; import { fetchInstance } from 'soapbox/actions/instance'; +import { getFeatures } from 'soapbox/utils/features'; import { isStandalone } from 'soapbox/utils/state'; import LoginForm from './login_form'; import OtpAuthForm from './otp_auth_form'; -const mapStateToProps = state => ({ - me: state.get('me'), - isLoading: false, - standalone: isStandalone(state), -}); +const mapStateToProps = state => { + const instance = state.get('instance'); + + return { + me: state.get('me'), + isLoading: false, + standalone: isStandalone(state), + features: getFeatures(instance), + }; +}; export default @connect(mapStateToProps) @injectIntl @@ -62,8 +69,18 @@ class LoginPage extends ImmutablePureComponent { event.preventDefault(); } + handleEthereumLogin = e => { + const { dispatch } = this.props; + + dispatch(ethereumLogin()) + .then(() => this.setState({ shouldRedirect: true })) + .catch(console.error); + + e.preventDefault(); + }; + render() { - const { standalone } = this.props; + const { standalone, features } = this.props; const { isLoading, mfa_auth_needed, mfa_token, shouldRedirect } = this.state; if (standalone) return ; @@ -72,7 +89,11 @@ class LoginPage extends ImmutablePureComponent { if (mfa_auth_needed) return ; - return ; + if (features.ethereumLogin) { + return ; + } else { + return ; + } } } diff --git a/app/soapbox/utils/features.js b/app/soapbox/utils/features.js index e55ca455c..2df8e1c7a 100644 --- a/app/soapbox/utils/features.js +++ b/app/soapbox/utils/features.js @@ -9,6 +9,7 @@ const any = arr => arr.some(Boolean); // For uglification export const MASTODON = 'Mastodon'; export const PLEROMA = 'Pleroma'; +export const MITRA = 'Mitra'; export const getFeatures = createSelector([ instance => parseVersion(instance.get('version')), @@ -83,6 +84,7 @@ export const getFeatures = createSelector([ accountEndorsements: v.software === PLEROMA && gte(v.version, '2.4.50'), quotePosts: v.software === PLEROMA && gte(v.version, '2.4.50'), birthdays: v.software === PLEROMA && gte(v.version, '2.4.50'), + ethereumLogin: v.software === MITRA, }; });