Fleet UI: When SES configured so no need for SMTP (#11064)
This commit is contained in:
@@ -119,7 +119,7 @@ Logs out the authenticated user.
|
||||
|
||||
### Forgot password
|
||||
|
||||
Sends a password reset email to the specified email. Requires that SMTP is configured for your Fleet server.
|
||||
Sends a password reset email to the specified email. Requires that SMTP or SES is configured for your Fleet server.
|
||||
|
||||
`POST /api/v1/fleet/forgot_password`
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ class UserSettingsForm extends Component {
|
||||
disabled={!smtpConfigured}
|
||||
tooltip={
|
||||
"\
|
||||
Editing your email address requires that SMTP is configured in order to send a validation email.\
|
||||
Editing your email address requires that SMTP or SES is configured in order to send a validation email.\
|
||||
<br /><br /> \
|
||||
Users with Admin role can configure SMTP in <strong>Settings > Organization settings</strong>.\
|
||||
"
|
||||
|
||||
@@ -78,6 +78,13 @@ export default PropTypes.shape({
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
email: PropTypes.shape({
|
||||
backend: PropTypes.string,
|
||||
config: PropTypes.shape({
|
||||
region: PropTypes.string,
|
||||
source_arn: PropTypes.string,
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
export interface ILicense {
|
||||
@@ -234,6 +241,13 @@ export interface IConfig {
|
||||
};
|
||||
};
|
||||
};
|
||||
email?: {
|
||||
backend: string;
|
||||
config: {
|
||||
region: string;
|
||||
source_arn: string;
|
||||
};
|
||||
};
|
||||
mdm: IMdmConfig;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,6 +77,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
.smtp-status {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.empty-table__container {
|
||||
margin: 96px 0 1.5rem;
|
||||
|
||||
@media (min-width: $break-990) {
|
||||
max-width: 65%;
|
||||
}
|
||||
}
|
||||
|
||||
.smtp-options {
|
||||
font-size: 15px;
|
||||
font-weight: $bold;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import React, { useState, useEffect, useContext } from "react";
|
||||
|
||||
import { AppContext } from "context/app";
|
||||
import Button from "components/buttons/Button";
|
||||
import Checkbox from "components/forms/fields/Checkbox";
|
||||
// @ts-ignore
|
||||
@@ -8,6 +9,8 @@ import Dropdown from "components/forms/fields/Dropdown";
|
||||
import InputField from "components/forms/fields/InputField";
|
||||
// @ts-ignore
|
||||
import validEmail from "components/forms/validators/valid_email";
|
||||
import EmptyTable from "components/EmptyTable";
|
||||
import CustomLink from "components/CustomLink";
|
||||
|
||||
import {
|
||||
IAppConfigFormProps,
|
||||
@@ -24,6 +27,8 @@ const Smtp = ({
|
||||
handleSubmit,
|
||||
isUpdatingSettings,
|
||||
}: IAppConfigFormProps): JSX.Element => {
|
||||
const { isPremiumTier } = useContext(AppContext);
|
||||
|
||||
const [formData, setFormData] = useState<any>({
|
||||
enableSMTP: appConfig.smtp_settings.enable_smtp || false,
|
||||
smtpSenderAddress: appConfig.smtp_settings.sender_address || "",
|
||||
@@ -51,6 +56,8 @@ const Smtp = ({
|
||||
|
||||
const [formErrors, setFormErrors] = useState<IAppConfigFormErrors>({});
|
||||
|
||||
const sesConfigured = appConfig.email?.backend === "ses" || false;
|
||||
|
||||
const handleInputChange = ({ name, value }: IFormField) => {
|
||||
setFormData({ ...formData, [name]: value });
|
||||
};
|
||||
@@ -158,26 +165,28 @@ const Smtp = ({
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<form className={baseClass} onSubmit={onFormSubmit} autoComplete="off">
|
||||
<div className={`${baseClass}__section`}>
|
||||
<h2>
|
||||
SMTP options{" "}
|
||||
<small
|
||||
className={`smtp-options smtp-options--${
|
||||
appConfig.smtp_settings.configured
|
||||
? "configured"
|
||||
: "notconfigured"
|
||||
}`}
|
||||
>
|
||||
STATUS:{" "}
|
||||
<em>
|
||||
{appConfig.smtp_settings.configured
|
||||
? "CONFIGURED"
|
||||
: "NOT CONFIGURED"}
|
||||
</em>
|
||||
</small>
|
||||
</h2>
|
||||
const renderSesEnabled = () => {
|
||||
const header = "Email already configured";
|
||||
const info = (
|
||||
<>
|
||||
To configure SMTP,{" "}
|
||||
<CustomLink
|
||||
url={
|
||||
isPremiumTier
|
||||
? "https://fleetdm.com/contact"
|
||||
: "https://fleetdm.com/slack"
|
||||
}
|
||||
text="get help"
|
||||
newTab
|
||||
/>
|
||||
</>
|
||||
);
|
||||
return <EmptyTable header={header} info={info} />;
|
||||
};
|
||||
|
||||
const renderSmtpForm = () => {
|
||||
return (
|
||||
<>
|
||||
<div className={`${baseClass}__inputs`}>
|
||||
<Checkbox
|
||||
onChange={handleInputChange}
|
||||
@@ -248,16 +257,43 @@ const Smtp = ({
|
||||
/>
|
||||
{renderSmtpSection()}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
return (
|
||||
<form className={baseClass} onSubmit={onFormSubmit} autoComplete="off">
|
||||
<div className={`${baseClass}__section`}>
|
||||
<h2 className={"smtp-status"}>
|
||||
SMTP options{" "}
|
||||
{!sesConfigured && (
|
||||
<small
|
||||
className={`smtp-options smtp-options--${
|
||||
appConfig.smtp_settings.configured
|
||||
? "configured"
|
||||
: "notconfigured"
|
||||
}`}
|
||||
>
|
||||
<em>
|
||||
{appConfig.smtp_settings.configured
|
||||
? "CONFIGURED"
|
||||
: "NOT CONFIGURED"}
|
||||
</em>
|
||||
</small>
|
||||
)}
|
||||
</h2>
|
||||
{sesConfigured ? renderSesEnabled() : renderSmtpForm()}
|
||||
</div>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="brand"
|
||||
disabled={Object.keys(formErrors).length > 0}
|
||||
className="save-loading"
|
||||
isLoading={isUpdatingSettings}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
{!sesConfigured && (
|
||||
<Button
|
||||
type="submit"
|
||||
variant="brand"
|
||||
disabled={Object.keys(formErrors).length > 0}
|
||||
className="save-loading"
|
||||
isLoading={isUpdatingSettings}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
)}
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -68,6 +68,7 @@ const MembersPage = ({ location, router }: IMembersPageProps): JSX.Element => {
|
||||
});
|
||||
|
||||
const smtpConfigured = config?.smtp_settings.configured || false;
|
||||
const sesConfigured = config?.email?.backend === "ses" || false;
|
||||
const canUseSso = config?.sso_settings.enable_sso || false;
|
||||
|
||||
const [showAddMemberModal, setShowAddMemberModal] = useState(false);
|
||||
@@ -477,6 +478,7 @@ const MembersPage = ({ location, router }: IMembersPageProps): JSX.Element => {
|
||||
availableTeams={teams || []}
|
||||
isPremiumTier={isPremiumTier || false}
|
||||
smtpConfigured={smtpConfigured}
|
||||
sesConfigured={sesConfigured}
|
||||
canUseSso={canUseSso}
|
||||
isSsoEnabled={userEditing?.sso_enabled}
|
||||
isModifiedByGlobalAdmin={isGlobalAdmin}
|
||||
@@ -498,6 +500,7 @@ const MembersPage = ({ location, router }: IMembersPageProps): JSX.Element => {
|
||||
availableTeams={teams}
|
||||
isPremiumTier={isPremiumTier || false}
|
||||
smtpConfigured={smtpConfigured}
|
||||
sesConfigured={sesConfigured}
|
||||
canUseSso={canUseSso}
|
||||
currentTeam={currentTeamDetails}
|
||||
isModifiedByGlobalAdmin={isGlobalAdmin}
|
||||
|
||||
@@ -15,6 +15,7 @@ interface ICreateUserModalProps {
|
||||
availableTeams?: ITeam[];
|
||||
isPremiumTier: boolean;
|
||||
smtpConfigured: boolean;
|
||||
sesConfigured: boolean;
|
||||
currentTeam?: ITeam;
|
||||
canUseSso: boolean; // corresponds to whether SSO is enabled for the organization
|
||||
isModifiedByGlobalAdmin?: boolean | false;
|
||||
@@ -35,6 +36,7 @@ const CreateUserModal = ({
|
||||
availableTeams,
|
||||
isPremiumTier,
|
||||
smtpConfigured,
|
||||
sesConfigured,
|
||||
canUseSso,
|
||||
isModifiedByGlobalAdmin,
|
||||
isUpdatingUsers,
|
||||
@@ -55,6 +57,7 @@ const CreateUserModal = ({
|
||||
submitText={"Create"}
|
||||
isPremiumTier={isPremiumTier}
|
||||
smtpConfigured={smtpConfigured}
|
||||
sesConfigured={sesConfigured}
|
||||
canUseSso={canUseSso}
|
||||
isModifiedByGlobalAdmin={isModifiedByGlobalAdmin}
|
||||
currentTeam={currentTeam}
|
||||
|
||||
@@ -18,6 +18,7 @@ interface IEditUserModalProps {
|
||||
currentTeam?: ITeam;
|
||||
isPremiumTier: boolean;
|
||||
smtpConfigured: boolean;
|
||||
sesConfigured: boolean;
|
||||
canUseSso: boolean; // corresponds to whether SSO is enabled for the organization
|
||||
isSsoEnabled?: boolean; // corresponds to whether SSO is enabled for the individual user
|
||||
isApiOnly?: boolean;
|
||||
@@ -40,6 +41,7 @@ const EditUserModal = ({
|
||||
availableTeams,
|
||||
isPremiumTier,
|
||||
smtpConfigured,
|
||||
sesConfigured,
|
||||
canUseSso,
|
||||
isSsoEnabled,
|
||||
isApiOnly,
|
||||
@@ -68,6 +70,7 @@ const EditUserModal = ({
|
||||
submitText={"Save"}
|
||||
isPremiumTier={isPremiumTier}
|
||||
smtpConfigured={smtpConfigured}
|
||||
sesConfigured={sesConfigured}
|
||||
canUseSso={canUseSso}
|
||||
isSsoEnabled={isSsoEnabled}
|
||||
isApiOnly={isApiOnly}
|
||||
|
||||
@@ -64,6 +64,7 @@ interface ICreateUserFormProps {
|
||||
defaultTeams?: ITeam[];
|
||||
isPremiumTier: boolean;
|
||||
smtpConfigured?: boolean;
|
||||
sesConfigured?: boolean;
|
||||
canUseSso: boolean; // corresponds to whether SSO is enabled for the organization
|
||||
isSsoEnabled?: boolean; // corresponds to whether SSO is enabled for the individual user
|
||||
isApiOnly?: boolean;
|
||||
@@ -89,6 +90,7 @@ const UserForm = ({
|
||||
defaultTeams,
|
||||
isPremiumTier,
|
||||
smtpConfigured,
|
||||
sesConfigured,
|
||||
canUseSso,
|
||||
isSsoEnabled,
|
||||
isApiOnly,
|
||||
@@ -394,10 +396,10 @@ const UserForm = ({
|
||||
onChange={onInputChange("email")}
|
||||
placeholder="Email"
|
||||
value={formData.email || ""}
|
||||
disabled={!isNewUser && !smtpConfigured}
|
||||
disabled={!isNewUser && !(smtpConfigured || sesConfigured)}
|
||||
tooltip={
|
||||
"\
|
||||
Editing an email address requires that SMTP is configured in order to send a validation email. \
|
||||
Editing an email address requires that SMTP or SES is configured in order to send a validation email. \
|
||||
<br /><br /> \
|
||||
Users with Admin role can configure SMTP in <strong>Settings > Organization settings</strong>. \
|
||||
"
|
||||
@@ -462,16 +464,16 @@ const UserForm = ({
|
||||
className={`${baseClass}__radio-input`}
|
||||
label={"Invite user"}
|
||||
id={"invite-user"}
|
||||
disabled={!smtpConfigured}
|
||||
disabled={!(smtpConfigured || sesConfigured)}
|
||||
checked={formData.newUserType === NewUserType.AdminInvited}
|
||||
value={NewUserType.AdminInvited}
|
||||
name={"newUserType"}
|
||||
onChange={onRadioChange("newUserType")}
|
||||
tooltip={
|
||||
smtpConfigured
|
||||
smtpConfigured || sesConfigured
|
||||
? ""
|
||||
: `
|
||||
The "Invite user" feature requires that SMTP
|
||||
The "Invite user" feature requires that SMTP or SES
|
||||
is configured in order to send invitation emails.
|
||||
<br /><br />
|
||||
SMTP can be configured in Settings > Organization settings.
|
||||
|
||||
@@ -444,6 +444,7 @@ const UsersTable = ({ router }: IUsersTableProps): JSX.Element => {
|
||||
availableTeams={teams || []}
|
||||
isPremiumTier={isPremiumTier || false}
|
||||
smtpConfigured={config?.smtp_settings.configured || false}
|
||||
sesConfigured={config?.email?.backend === "ses" || false}
|
||||
canUseSso={config?.sso_settings.enable_sso || false}
|
||||
isSsoEnabled={userData?.sso_enabled}
|
||||
isApiOnly={userData?.api_only || false}
|
||||
@@ -468,6 +469,7 @@ const UsersTable = ({ router }: IUsersTableProps): JSX.Element => {
|
||||
defaultTeams={[]}
|
||||
isPremiumTier={isPremiumTier || false}
|
||||
smtpConfigured={config?.smtp_settings.configured || false}
|
||||
sesConfigured={config?.email?.backend === "ses" || false}
|
||||
canUseSso={config?.sso_settings.enable_sso || false}
|
||||
isUpdatingUsers={isUpdatingUsers}
|
||||
isModifiedByGlobalAdmin
|
||||
|
||||
Reference in New Issue
Block a user