stitch-ui
Version:
400 lines (387 loc) • 14 kB
JavaScript
// TODO proptypes
/* eslint-disable react/prop-types */
/* eslint-disable no-shadow */
import React from "react"; // eslint-disable-line no-unused-vars
import { connect } from "react-redux";
import { addAlert } from "../../alert";
import { Banner } from "../../core";
import {
loadProviders,
enableProvider,
disableProvider,
discardProviderUpdates,
openProvider,
setSigningKey,
setProviderClientIdInput,
setProviderClientSecretInput,
setRedirectURIInput,
removeRedirectURI,
addRedirectURI,
addDomainRestriction,
removeDomainRestriction,
setDomainRestrictionInput,
setMetadataField,
apiKeyActions,
setResetPasswordURL,
setEmailConfirmationURL,
setResetPasswordSubject,
setEmailConfirmationSubject
} from "../actions";
import AuthProviderInput from "./AuthProviderInput";
import AuthProvider from "./AuthProvider";
import EmailPassword from "./EmailPassword";
import APIKeys from "./APIKeys";
const GOOGLE = "oauth2/google";
const FACEBOOK = "oauth2/facebook";
const CUSTOM = "custom/token";
const USERPASS = "local/userpass";
const APIKEY = "api/key";
const makeAlertKey = provider => `auth/${provider}`;
class AuthProviders extends React.Component {
constructor(props) {
super(props);
this.makeProviderInput = this.makeProviderInput.bind(this);
}
componentDidMount() {
this.props.loadProviders();
this.props.loadAPIKeys();
}
enableProvider(type, name, data) {
return this.props
.enableProvider(type, name, data)
.then(this.props.loadProviders);
}
disableProvider(type, name) {
return this.props
.disableProvider(type, name)
.then(this.props.loadProviders);
}
discardProviderUpdates() {
return this.props.discardProviderUpdates();
}
makeProviderInput(provider, isOAuth) {
const [name, type] = provider.split("/");
const {
addAlert,
loadProviders,
enableProvider,
disableProvider,
providersInput,
setProviderClientIdInput,
setProviderClientSecretInput,
setSigningKey,
setRedirectURIInput,
removeRedirectURI,
addRedirectURI,
addDomainRestriction,
removeDomainRestriction,
setDomainRestrictionInput,
setMetadataField,
discardProviderUpdates
} = this.props;
return (
<AuthProviderInput
oauth={isOAuth}
availableMetadataFields={["name", "picture", "email"]}
providerInput={providersInput.get(provider)}
setProviderClientIdInput={input =>
setProviderClientIdInput(provider, input)}
setProviderClientSecretInput={input =>
setProviderClientSecretInput(provider, input)}
setRedirectURIInput={(index, input) =>
setRedirectURIInput(provider, index, input)}
addRedirectURI={() => addRedirectURI(provider)}
setSigningKey={input => setSigningKey(provider, input)}
removeRedirectURI={index => removeRedirectURI(provider, index)}
addDomainRestriction={() => addDomainRestriction(provider)}
removeDomainRestriction={index =>
removeDomainRestriction(provider, index)}
setDomainRestrictionInput={(index, input) =>
setDomainRestrictionInput(provider, index, input)}
setMetadataField={(field, enabled) =>
setMetadataField(provider, field, enabled)}
alertKey={makeAlertKey(provider)}
save={() => {
const providerInput = providersInput.get(provider);
if (providerInput) {
let providerToSave = providerInput.toJS();
delete providerToSave.error;
delete providerToSave.dirty;
providerToSave = {
...providerToSave,
redirectURIs: (providerToSave.redirectURIs || []).filter(r => r),
domainRestrictions: (providerToSave.domainRestrictions || [])
.filter(r => r)
};
return enableProvider(name, type, providerToSave)
.then(() => addAlert(makeAlertKey(provider), "Saved"))
.then(loadProviders)
.catch(() => {});
}
return disableProvider(name, type)
.then(() => addAlert(makeAlertKey(provider), "Saved"))
.then(loadProviders)
.catch(() => {});
}}
discard={() => {
discardProviderUpdates();
return addAlert(makeAlertKey(provider), "Discarded");
}}
/>
);
}
render() {
const {
providers,
providersInput,
error,
openProvider,
discardProviderUpdates
} = this.props;
const { apiKeys } = this.props;
/* API Key actions. */
const {
apiKeyError,
newKeyName,
loadAPIKeys,
deleteAPIKey,
disableAPIKey,
enableAPIKey,
createAPIKey,
getAPIKey,
hideAPIKey,
setNewKeyName,
showNewKeyForm,
openNewKeyForm,
setAPIKeyHidden,
closeNewKeyForm,
setResetPasswordURL,
setEmailConfirmationURL,
setResetPasswordSubject,
setEmailConfirmationSubject
} = this.props;
return (
<table className="plain-table">
<thead>
<tr className="plain-table-header-row">
<th className="plain-table-column-header">Provider</th>
<th className="plain-table-column-header">Status</th>
<th className="plain-table-column-header" />
</tr>
</thead>
<tbody>
<Banner message={error} error />
<AuthProvider
title="Allow users to log in anonymously"
open={
providers !== undefined &&
Object.prototype.hasOwnProperty.call(providers, "anon/user")
}
enableProvider={() => this.enableProvider("anon", "user", {})}
disableProvider={() => this.disableProvider("anon", "user")}
confirmBeforeClose={false}
/>
<AuthProvider
title="Email/Password"
open={providersInput.has(USERPASS)}
enableProvider={() => openProvider(USERPASS)}
disableProvider={() => this.disableProvider("local", "userpass")}
confirmBeforeClose
>
<EmailPassword
setResetPasswordURL={input =>
setResetPasswordURL(USERPASS, input)}
setEmailConfirmationURL={input =>
setEmailConfirmationURL(USERPASS, input)}
setEmailConfirmationSubject={input =>
setEmailConfirmationSubject(USERPASS, input)}
setResetPasswordSubject={input =>
setResetPasswordSubject(USERPASS, input)}
providerInput={providersInput.get(USERPASS)}
alertKey={makeAlertKey(USERPASS)}
save={() => {
const providerInput = providersInput.get(USERPASS);
if (providerInput) {
const providerToSave = providerInput.toJS();
delete providerToSave.error;
delete providerToSave.dirty;
return this.enableProvider(
"local",
"userpass",
providerToSave
)
.then(() =>
this.props.addAlert(makeAlertKey(USERPASS), "Saved")
)
.then(loadProviders)
.catch(() => {});
}
return this.disableProvider("local", "userpass")
.then(() =>
this.props.addAlert(makeAlertKey(USERPASS), "Saved")
)
.then(loadProviders)
.catch(() => {});
}}
discard={() => {
discardProviderUpdates();
return this.props.addAlert(makeAlertKey(USERPASS), "Discarded");
}}
/>
</AuthProvider>
<AuthProvider
title="Google"
open={providersInput.has(GOOGLE)}
enableProvider={() => openProvider(GOOGLE)}
disableProvider={() => this.disableProvider("oauth2", "google")}
confirmBeforeClose
>
{this.makeProviderInput(GOOGLE, true)}
</AuthProvider>
<AuthProvider
title="Facebook"
open={providersInput.has(FACEBOOK)}
enableProvider={() => openProvider(FACEBOOK)}
disableProvider={() => this.disableProvider("oauth2", "facebook")}
confirmBeforeClose
>
{this.makeProviderInput(FACEBOOK, true)}
</AuthProvider>
<AuthProvider
title="API Keys"
confirmBeforeClose={false}
open={providersInput.has(APIKEY)}
enableProvider={() => this.enableProvider("api", "key", {})}
disableProvider={() => this.disableProvider("api", "key")}
tooltip="An API Key will allow others clients to connect with your app without needing a password."
>
<APIKeys
apiKeyError={apiKeyError}
newKeyName={newKeyName}
apiKeys={apiKeys}
setAPIKeyHidden={setAPIKeyHidden}
loadAPIKeys={loadAPIKeys}
deleteAPIKey={deleteAPIKey}
disableAPIKey={disableAPIKey}
enableAPIKey={enableAPIKey}
createAPIKey={createAPIKey}
getAPIKey={getAPIKey}
hideAPIKey={hideAPIKey}
showNewKeyForm={showNewKeyForm}
setNewKeyName={setNewKeyName}
openNewKeyForm={openNewKeyForm}
closeNewKeyForm={closeNewKeyForm}
/>
</AuthProvider>
<AuthProvider
title="Custom Authentication"
open={providersInput.has(CUSTOM)}
enableProvider={() => openProvider(CUSTOM)}
disableProvider={() => this.disableProvider("custom", "token")}
confirmBeforeClose
tooltip="Stitch allows developers to issue custom credentials to users of their app. Custom authentication requires each user to have an ID which is unique within the app."
>
{this.makeProviderInput(CUSTOM, false)}
</AuthProvider>
</tbody>
</table>
);
}
}
const mapStateToProps = state => {
const {
providers,
providersInput,
togglingProvider,
loadingProviders,
error
} = state.auth.auth;
const {
apiKeys,
showNewKeyForm,
newKeyName,
apiKeyError
} = state.auth.apiKeys;
return {
providers,
providersInput,
togglingProvider,
error,
loadingProviders,
apiKeys,
newKeyName,
showNewKeyForm,
apiKeyError
};
};
const mapDispatchToProps = (dispatch, ownProps) => ({
addAlert: (key, message) => dispatch(addAlert(key, message)),
loadProviders: () =>
dispatch(loadProviders(ownProps.app.groupId, ownProps.app._id)),
openProvider: provider => dispatch(openProvider({ provider })),
setSigningKey: (provider, input) =>
dispatch(setSigningKey({ provider, input })),
enableProvider: (type, name, data) =>
dispatch(
enableProvider(ownProps.app.groupId, ownProps.app._id, type, name, data)
),
disableProvider: (type, name) =>
dispatch(
disableProvider(ownProps.app.groupId, ownProps.app._id, type, name)
),
discardProviderUpdates: () => dispatch(discardProviderUpdates()),
setResetPasswordSubject: (provider, input) =>
dispatch(setResetPasswordSubject({ provider, input })),
setEmailConfirmationSubject: (provider, input) =>
dispatch(setEmailConfirmationSubject({ provider, input })),
setResetPasswordURL: (provider, input) =>
dispatch(setResetPasswordURL({ provider, input })),
setEmailConfirmationURL: (provider, input) =>
dispatch(setEmailConfirmationURL({ provider, input })),
setProviderClientIdInput: (provider, input) =>
dispatch(setProviderClientIdInput({ provider, input })),
setProviderClientSecretInput: (provider, input) =>
dispatch(setProviderClientSecretInput({ provider, input })),
setRedirectURIInput: (provider, index, input) =>
dispatch(setRedirectURIInput({ provider, index, input })),
removeRedirectURI: (provider, index) =>
dispatch(removeRedirectURI({ provider, index })),
addRedirectURI: provider => dispatch(addRedirectURI({ provider })),
addDomainRestriction: provider =>
dispatch(addDomainRestriction({ provider })),
removeDomainRestriction: (provider, index) =>
dispatch(removeDomainRestriction({ provider, index })),
setDomainRestrictionInput: (provider, index, input) =>
dispatch(setDomainRestrictionInput({ provider, index, input })),
setMetadataField: (provider, field, enabled) =>
dispatch(setMetadataField({ provider, field, enabled })),
loadAPIKeys: () =>
dispatch(apiKeyActions.loadAPIKeys(ownProps.app.groupId, ownProps.app._id)),
deleteAPIKey: key =>
dispatch(
apiKeyActions.deleteAPIKey(ownProps.app.groupId, ownProps.app._id, key)
),
disableAPIKey: key =>
dispatch(
apiKeyActions.disableAPIKey(ownProps.app.groupId, ownProps.app._id, key)
),
enableAPIKey: key =>
dispatch(
apiKeyActions.enableAPIKey(ownProps.app.groupId, ownProps.app._id, key)
),
getAPIKey: key =>
dispatch(
apiKeyActions.getAPIKey(ownProps.app.groupId, ownProps.app._id, key)
),
hideAPIKey: key => dispatch(apiKeyActions.hideAPIKey({ key })),
setAPIKeyHidden: (key, hidden) =>
dispatch(apiKeyActions.setAPIKeyHidden({ key, hidden })),
openNewKeyForm: () => dispatch(apiKeyActions.openNewKeyForm()),
setNewKeyName: name => dispatch(apiKeyActions.setNewKeyName({ name })),
closeNewKeyForm: () => dispatch(apiKeyActions.closeNewKeyForm()),
createAPIKey: data =>
dispatch(
apiKeyActions.createAPIKey(ownProps.app.groupId, ownProps.app._id, data)
)
});
export default connect(mapStateToProps, mapDispatchToProps)(AuthProviders);