feat: Add minor settings improvements (#4626)

This commit is contained in:
Bruno Quaresma
2022-10-18 16:25:52 -03:00
committed by GitHub
parent 0d67dfc215
commit 906046c1cc
7 changed files with 255 additions and 630 deletions

View File

@ -6,7 +6,7 @@ import React from "react"
export const Header: React.FC<{ export const Header: React.FC<{
title: string | JSX.Element title: string | JSX.Element
description: string | JSX.Element description?: string | JSX.Element
secondary?: boolean secondary?: boolean
docsHref?: string docsHref?: string
}> = ({ title, description, docsHref, secondary }) => { }> = ({ title, description, docsHref, secondary }) => {
@ -18,7 +18,9 @@ export const Header: React.FC<{
<h1 className={`${styles.title} ${secondary ? "secondary" : ""}`}> <h1 className={`${styles.title} ${secondary ? "secondary" : ""}`}>
{title} {title}
</h1> </h1>
<span className={styles.description}>{description}</span> {description && (
<span className={styles.description}>{description}</span>
)}
</div> </div>
{docsHref && ( {docsHref && (

View File

@ -1,6 +1,7 @@
import { makeStyles } from "@material-ui/core/styles" import { makeStyles } from "@material-ui/core/styles"
import React, { PropsWithChildren } from "react" import React, { PropsWithChildren } from "react"
import { MONOSPACE_FONT_FAMILY } from "theme/constants" import { MONOSPACE_FONT_FAMILY } from "theme/constants"
import { DisabledBadge, EnabledBadge } from "./Badges"
export const OptionName: React.FC<PropsWithChildren> = ({ children }) => { export const OptionName: React.FC<PropsWithChildren> = ({ children }) => {
const styles = useStyles() const styles = useStyles()
@ -14,8 +15,39 @@ export const OptionDescription: React.FC<PropsWithChildren> = ({
return <span className={styles.optionDescription}>{children}</span> return <span className={styles.optionDescription}>{children}</span>
} }
const NotSet: React.FC = () => {
const styles = useStyles()
return <span className={styles.optionValue}>Not set</span>
}
export const OptionValue: React.FC<PropsWithChildren> = ({ children }) => { export const OptionValue: React.FC<PropsWithChildren> = ({ children }) => {
const styles = useStyles() const styles = useStyles()
if (typeof children === "boolean") {
return children ? <EnabledBadge /> : <DisabledBadge />
}
if (Array.isArray(children)) {
if (children.length === 0) {
return <NotSet />
}
return (
<ul className={styles.optionValueList}>
{children.map((item) => (
<li key={item} className={styles.optionValue}>
{item}
</li>
))}
</ul>
)
}
if (children === "") {
return <NotSet />
}
return <span className={styles.optionValue}>{children}</span> return <span className={styles.optionValue}>{children}</span>
} }
@ -23,18 +55,31 @@ const useStyles = makeStyles((theme) => ({
optionName: { optionName: {
display: "block", display: "block",
}, },
optionDescription: { optionDescription: {
display: "block", display: "block",
color: theme.palette.text.secondary, color: theme.palette.text.secondary,
fontSize: 14, fontSize: 14,
marginTop: theme.spacing(0.5), marginTop: theme.spacing(0.5),
}, },
optionValue: { optionValue: {
fontSize: 14, fontSize: 14,
fontFamily: MONOSPACE_FONT_FAMILY, fontFamily: MONOSPACE_FONT_FAMILY,
overflowWrap: "anywhere",
userSelect: "all",
"& ul": { "& ul": {
padding: theme.spacing(2), padding: theme.spacing(2),
}, },
}, },
optionValueList: {
margin: 0,
padding: 0,
listStylePosition: "inside",
display: "flex",
flexDirection: "column",
gap: theme.spacing(0.5),
},
})) }))

View File

@ -0,0 +1,64 @@
import { makeStyles } from "@material-ui/core/styles"
import Table from "@material-ui/core/Table"
import TableBody from "@material-ui/core/TableBody"
import TableCell from "@material-ui/core/TableCell"
import TableContainer from "@material-ui/core/TableContainer"
import TableHead from "@material-ui/core/TableHead"
import TableRow from "@material-ui/core/TableRow"
import { DeploymentFlags } from "api/typesGenerated"
import {
OptionDescription,
OptionName,
OptionValue,
} from "components/DeploySettingsLayout/Option"
import React from "react"
const OptionsTable: React.FC<{ options: Partial<DeploymentFlags> }> = ({
options,
}) => {
const styles = useStyles()
return (
<TableContainer>
<Table className={styles.table}>
<TableHead>
<TableRow>
<TableCell width="50%">Option</TableCell>
<TableCell width="50%">Value</TableCell>
</TableRow>
</TableHead>
<TableBody>
{Object.values(options).map((option) => {
return (
<TableRow key={option.flag}>
<TableCell>
<OptionName>{option.name}</OptionName>
<OptionDescription>{option.description}</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>{option.value}</OptionValue>
</TableCell>
</TableRow>
)
})}
</TableBody>
</Table>
</TableContainer>
)
}
const useStyles = makeStyles((theme) => ({
table: {
"& td": {
paddingTop: theme.spacing(3),
paddingBottom: theme.spacing(3),
},
"& td:last-child, & th:last-child": {
paddingLeft: theme.spacing(4),
},
},
}))
export default OptionsTable

View File

@ -1,9 +1,3 @@
import Table from "@material-ui/core/Table"
import TableBody from "@material-ui/core/TableBody"
import TableCell from "@material-ui/core/TableCell"
import TableContainer from "@material-ui/core/TableContainer"
import TableHead from "@material-ui/core/TableHead"
import TableRow from "@material-ui/core/TableRow"
import { import {
Badges, Badges,
DisabledBadge, DisabledBadge,
@ -11,21 +5,25 @@ import {
} from "components/DeploySettingsLayout/Badges" } from "components/DeploySettingsLayout/Badges"
import { useDeploySettings } from "components/DeploySettingsLayout/DeploySettingsLayout" import { useDeploySettings } from "components/DeploySettingsLayout/DeploySettingsLayout"
import { Header } from "components/DeploySettingsLayout/Header" import { Header } from "components/DeploySettingsLayout/Header"
import { import OptionsTable from "components/DeploySettingsLayout/OptionsTable"
OptionDescription,
OptionName,
OptionValue,
} from "components/DeploySettingsLayout/Option"
import { Stack } from "components/Stack/Stack" import { Stack } from "components/Stack/Stack"
import React from "react" import React from "react"
import { Helmet } from "react-helmet-async"
import { pageTitle } from "util/page"
const AuthSettingsPage: React.FC = () => { const AuthSettingsPage: React.FC = () => {
const { deploymentFlags } = useDeploySettings() const { deploymentFlags } = useDeploySettings()
return ( return (
<> <>
<Helmet>
<title>{pageTitle("Authentication Settings")}</title>
</Helmet>
<Stack direction="column" spacing={6}> <Stack direction="column" spacing={6}>
<div> <div>
<Header title="Authentication" />
<Header <Header
title="Login with OpenID Connect" title="Login with OpenID Connect"
secondary secondary
@ -41,121 +39,16 @@ const AuthSettingsPage: React.FC = () => {
)} )}
</Badges> </Badges>
<TableContainer> <OptionsTable
<Table> options={{
<TableHead> oidc_client_id: deploymentFlags.oidc_client_id,
<TableRow> oidc_client_secret: deploymentFlags.oidc_client_secret,
<TableCell width="50%">Option</TableCell> oidc_allow_signups: deploymentFlags.oidc_allow_signups,
<TableCell width="50%">Value</TableCell> oidc_email_domain: deploymentFlags.oidc_email_domain,
</TableRow> oidc_issuer_url: deploymentFlags.oidc_issuer_url,
</TableHead> oidc_scopes: deploymentFlags.oidc_scopes,
<TableBody> }}
<TableRow> />
<TableCell>
<OptionName>
{deploymentFlags.oidc_client_id.name}
</OptionName>
<OptionDescription>
{deploymentFlags.oidc_client_id.description}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>
{deploymentFlags.oidc_client_id.value}
</OptionValue>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<OptionName>
{deploymentFlags.oidc_client_secret.name}
</OptionName>
<OptionDescription>
{deploymentFlags.oidc_client_secret.description}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>
{deploymentFlags.oidc_client_secret.value}
</OptionValue>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<OptionName>
{deploymentFlags.oidc_allow_signups.name}
</OptionName>
<OptionDescription>
{deploymentFlags.oidc_allow_signups.description}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>
{deploymentFlags.oidc_allow_signups.value.toString()}
</OptionValue>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<OptionName>
{deploymentFlags.oidc_email_domain.name}
</OptionName>
<OptionDescription>
{deploymentFlags.oidc_email_domain.description}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>
{deploymentFlags.oidc_email_domain.value}
</OptionValue>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<OptionName>
{deploymentFlags.oidc_issuer_url.name}
</OptionName>
<OptionDescription>
{deploymentFlags.oidc_issuer_url.description}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>
{deploymentFlags.oidc_issuer_url.value}
</OptionValue>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<OptionName>{deploymentFlags.oidc_scopes.name}</OptionName>
<OptionDescription>
{deploymentFlags.oidc_scopes.description}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>
<ul>
{deploymentFlags.oidc_scopes.value.map((scope) => (
<li key={scope}>{scope}</li>
))}
</ul>
</OptionValue>
</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
</div> </div>
<div> <div>
@ -174,137 +67,21 @@ const AuthSettingsPage: React.FC = () => {
)} )}
</Badges> </Badges>
<TableContainer> <OptionsTable
<Table> options={{
<TableHead> oauth2_github_client_id: deploymentFlags.oauth2_github_client_id,
<TableRow> oauth2_github_client_secret:
<TableCell width="50%">Option</TableCell> deploymentFlags.oauth2_github_client_secret,
<TableCell width="50%">Value</TableCell> oauth2_github_allow_signups:
</TableRow> deploymentFlags.oauth2_github_allow_signups,
</TableHead> oauth2_github_allowed_organizations:
<TableBody> deploymentFlags.oauth2_github_allowed_organizations,
<TableRow> oauth2_github_allowed_teams:
<TableCell> deploymentFlags.oauth2_github_allowed_teams,
<OptionName> oauth2_github_enterprise_base_url:
{deploymentFlags.oauth2_github_client_id.name} deploymentFlags.oauth2_github_enterprise_base_url,
</OptionName> }}
<OptionDescription> />
{deploymentFlags.oauth2_github_client_id.description}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>
{deploymentFlags.oauth2_github_client_id.value}
</OptionValue>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<OptionName>
{deploymentFlags.oauth2_github_client_secret.name}
</OptionName>
<OptionDescription>
{deploymentFlags.oauth2_github_client_secret.description}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>
{deploymentFlags.oauth2_github_client_secret.value}
</OptionValue>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<OptionName>
{deploymentFlags.oauth2_github_allow_signups.name}
</OptionName>
<OptionDescription>
{deploymentFlags.oauth2_github_allow_signups.description}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>
{deploymentFlags.oauth2_github_allow_signups.value.toString()}
</OptionValue>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<OptionName>
{deploymentFlags.oauth2_github_allowed_organizations.name}
</OptionName>
<OptionDescription>
{
deploymentFlags.oauth2_github_allowed_organizations
.description
}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>
<ul>
{deploymentFlags.oauth2_github_allowed_organizations.value.map(
(org) => (
<li key={org}>{org}</li>
),
)}
</ul>
</OptionValue>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<OptionName>
{deploymentFlags.oauth2_github_allowed_teams.name}
</OptionName>
<OptionDescription>
{deploymentFlags.oauth2_github_allowed_teams.description}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>
<ul>
{deploymentFlags.oauth2_github_allowed_teams.value.map(
(team) => (
<li key={team}>{team}</li>
),
)}
</ul>
</OptionValue>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<OptionName>
{deploymentFlags.oauth2_github_enterprise_base_url.name}
</OptionName>
<OptionDescription>
{
deploymentFlags.oauth2_github_enterprise_base_url
.description
}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>
{deploymentFlags.oauth2_github_enterprise_base_url.value}
</OptionValue>
</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
</div> </div>
</Stack> </Stack>
</> </>

View File

@ -1,83 +1,32 @@
import Table from "@material-ui/core/Table"
import TableBody from "@material-ui/core/TableBody"
import TableCell from "@material-ui/core/TableCell"
import TableContainer from "@material-ui/core/TableContainer"
import TableHead from "@material-ui/core/TableHead"
import TableRow from "@material-ui/core/TableRow"
import { useDeploySettings } from "components/DeploySettingsLayout/DeploySettingsLayout" import { useDeploySettings } from "components/DeploySettingsLayout/DeploySettingsLayout"
import { Header } from "components/DeploySettingsLayout/Header" import { Header } from "components/DeploySettingsLayout/Header"
import { import OptionsTable from "components/DeploySettingsLayout/OptionsTable"
OptionDescription,
OptionName,
OptionValue,
} from "components/DeploySettingsLayout/Option"
import React from "react" import React from "react"
import { Helmet } from "react-helmet-async"
import { pageTitle } from "util/page"
const GeneralSettingsPage: React.FC = () => { const GeneralSettingsPage: React.FC = () => {
const { deploymentFlags } = useDeploySettings() const { deploymentFlags } = useDeploySettings()
return ( return (
<> <>
<Helmet>
<title>{pageTitle("General Settings")}</title>
</Helmet>
<Header <Header
title="General" title="General"
description="Information about your Coder deployment." description="Information about your Coder deployment."
docsHref="https://coder.com/docs/coder-oss/latest/admin/configure" docsHref="https://coder.com/docs/coder-oss/latest/admin/configure"
/> />
<TableContainer> <OptionsTable
<Table> options={{
<TableHead> access_url: deploymentFlags.access_url,
<TableRow> address: deploymentFlags.address,
<TableCell width="50%">Option</TableCell> wildcard_access_url: deploymentFlags.wildcard_access_url,
<TableCell width="50%">Value</TableCell> }}
</TableRow> />
</TableHead>
<TableBody>
<TableRow>
<TableCell>
<OptionName>{deploymentFlags.access_url.name}</OptionName>
<OptionDescription>
{deploymentFlags.access_url.description}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>{deploymentFlags.access_url.value}</OptionValue>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<OptionName>{deploymentFlags.address.name}</OptionName>
<OptionDescription>
{deploymentFlags.address.description}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>{deploymentFlags.address.value}</OptionValue>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<OptionName>
{deploymentFlags.wildcard_access_url.name}
</OptionName>
<OptionDescription>
{deploymentFlags.wildcard_access_url.description}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>
{deploymentFlags.wildcard_access_url.value}
</OptionValue>
</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
</> </>
) )
} }

View File

@ -1,120 +1,34 @@
import Table from "@material-ui/core/Table"
import TableBody from "@material-ui/core/TableBody"
import TableCell from "@material-ui/core/TableCell"
import TableContainer from "@material-ui/core/TableContainer"
import TableHead from "@material-ui/core/TableHead"
import TableRow from "@material-ui/core/TableRow"
import {
DisabledBadge,
EnabledBadge,
} from "components/DeploySettingsLayout/Badges"
import { useDeploySettings } from "components/DeploySettingsLayout/DeploySettingsLayout" import { useDeploySettings } from "components/DeploySettingsLayout/DeploySettingsLayout"
import { Header } from "components/DeploySettingsLayout/Header" import { Header } from "components/DeploySettingsLayout/Header"
import { import OptionsTable from "components/DeploySettingsLayout/OptionsTable"
OptionDescription,
OptionName,
OptionValue,
} from "components/DeploySettingsLayout/Option"
import { Stack } from "components/Stack/Stack"
import React from "react" import React from "react"
import { Helmet } from "react-helmet-async"
import { pageTitle } from "util/page"
const NetworkSettingsPage: React.FC = () => { const NetworkSettingsPage: React.FC = () => {
const { deploymentFlags } = useDeploySettings() const { deploymentFlags } = useDeploySettings()
return ( return (
<Stack direction="column" spacing={6}> <>
<div> <Helmet>
<Header <title>{pageTitle("Network Settings")}</title>
title="Network" </Helmet>
description="Configure your deployment connectivity."
docsHref="https://coder.com/docs/coder-oss/latest/networking"
/>
<TableContainer> <Header
<Table> title="Network"
<TableHead> description="Configure your deployment connectivity."
<TableRow> docsHref="https://coder.com/docs/coder-oss/latest/admin/networking"
<TableCell width="50%">Option</TableCell> />
<TableCell width="50%">Value</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>
<OptionName>
{deploymentFlags.derp_server_enabled.name}
</OptionName>
<OptionDescription>
{deploymentFlags.derp_server_enabled.description}
</OptionDescription>
</TableCell>
<TableCell> <OptionsTable
<OptionValue> options={{
{deploymentFlags.derp_server_enabled.value ? ( derp_server_enabled: deploymentFlags.derp_server_enabled,
<EnabledBadge /> derp_server_region_name: deploymentFlags.derp_server_region_name,
) : ( derp_server_stun_address: deploymentFlags.derp_server_stun_address,
<DisabledBadge /> derp_config_url: deploymentFlags.derp_config_url,
)} }}
</OptionValue> />
</TableCell> </>
</TableRow>
<TableRow>
<TableCell>
<OptionName>
{deploymentFlags.derp_server_region_name.name}
</OptionName>
<OptionDescription>
{deploymentFlags.derp_server_region_name.description}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>
{deploymentFlags.derp_server_region_name.value}
</OptionValue>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<OptionName>
{deploymentFlags.derp_server_stun_address.name}
</OptionName>
<OptionDescription>
{deploymentFlags.derp_server_stun_address.description}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>
{deploymentFlags.derp_server_stun_address.value}
</OptionValue>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<OptionName>
{deploymentFlags.derp_config_url.name}
</OptionName>
<OptionDescription>
{deploymentFlags.derp_config_url.description}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>
{deploymentFlags.derp_config_url.value}
</OptionValue>
</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
</div>
</Stack>
) )
} }

View File

@ -1,9 +1,3 @@
import Table from "@material-ui/core/Table"
import TableBody from "@material-ui/core/TableBody"
import TableCell from "@material-ui/core/TableCell"
import TableContainer from "@material-ui/core/TableContainer"
import TableHead from "@material-ui/core/TableHead"
import TableRow from "@material-ui/core/TableRow"
import { useActor } from "@xstate/react" import { useActor } from "@xstate/react"
import { FeatureNames } from "api/types" import { FeatureNames } from "api/types"
import { import {
@ -14,13 +8,11 @@ import {
} from "components/DeploySettingsLayout/Badges" } from "components/DeploySettingsLayout/Badges"
import { useDeploySettings } from "components/DeploySettingsLayout/DeploySettingsLayout" import { useDeploySettings } from "components/DeploySettingsLayout/DeploySettingsLayout"
import { Header } from "components/DeploySettingsLayout/Header" import { Header } from "components/DeploySettingsLayout/Header"
import { import OptionsTable from "components/DeploySettingsLayout/OptionsTable"
OptionDescription,
OptionName,
OptionValue,
} from "components/DeploySettingsLayout/Option"
import { Stack } from "components/Stack/Stack" import { Stack } from "components/Stack/Stack"
import React, { useContext } from "react" import React, { useContext } from "react"
import { Helmet } from "react-helmet-async"
import { pageTitle } from "util/page"
import { XServiceContext } from "xServices/StateContext" import { XServiceContext } from "xServices/StateContext"
const SecuritySettingsPage: React.FC = () => { const SecuritySettingsPage: React.FC = () => {
@ -29,201 +21,83 @@ const SecuritySettingsPage: React.FC = () => {
const [entitlementsState] = useActor(xServices.entitlementsXService) const [entitlementsState] = useActor(xServices.entitlementsXService)
return ( return (
<Stack direction="column" spacing={6}> <>
<div> <Helmet>
<Header <title>{pageTitle("Security Settings")}</title>
title="Security" </Helmet>
description="Ensure your Coder deployment is secure." <Stack direction="column" spacing={6}>
/> <div>
<Header
title="Security"
description="Ensure your Coder deployment is secure."
/>
<TableContainer> <OptionsTable
<Table> options={{
<TableHead> ssh_keygen_algorithm: deploymentFlags.ssh_keygen_algorithm,
<TableRow> secure_auth_cookie: deploymentFlags.secure_auth_cookie,
<TableCell width="50%">Option</TableCell> }}
<TableCell width="50%">Value</TableCell> />
</TableRow> </div>
</TableHead>
<TableBody>
<TableRow>
<TableCell>
<OptionName>
{deploymentFlags.ssh_keygen_algorithm.name}
</OptionName>
<OptionDescription>
{deploymentFlags.ssh_keygen_algorithm.description}
</OptionDescription>
</TableCell>
<TableCell> <div>
<OptionValue> <Header
{deploymentFlags.ssh_keygen_algorithm.value} title="Audit Logging"
</OptionValue> secondary
</TableCell> description="Allow auditors to monitor user operations in your deployment."
</TableRow> docsHref="https://coder.com/docs/coder-oss/latest/admin/audit-logs"
<TableRow> />
<TableCell>
<OptionName>
{deploymentFlags.secure_auth_cookie.name}
</OptionName>
<OptionDescription>
{deploymentFlags.secure_auth_cookie.description}
</OptionDescription>
</TableCell>
<TableCell> <Badges>
<OptionValue> {entitlementsState.context.entitlements.features[
{deploymentFlags.secure_auth_cookie.value ? ( FeatureNames.AuditLog
<EnabledBadge /> ].enabled ? (
) : ( <EnabledBadge />
<DisabledBadge /> ) : (
)} <DisabledBadge />
</OptionValue> )}
</TableCell> <EnterpriseBadge />
</TableRow> </Badges>
</TableBody> </div>
</Table>
</TableContainer>
</div>
<div> <div>
<Header <Header
title="Audit Logging" title="Browser Only Connections"
secondary secondary
description="Allow auditors to monitor user operations in your deployment." description="Block all workspace access via SSH, port forward, and other non-browser connections."
docsHref="https://coder.com/docs/coder-oss/latest/admin/audit-logs" docsHref="https://coder.com/docs/coder-oss/latest/networking#browser-only-connections-enterprise"
/> />
<Badges> <Badges>
{entitlementsState.context.entitlements.features[ {entitlementsState.context.entitlements.features[
FeatureNames.AuditLog FeatureNames.BrowserOnly
].enabled ? ( ].enabled ? (
<EnabledBadge /> <EnabledBadge />
) : ( ) : (
<DisabledBadge /> <DisabledBadge />
)} )}
<EnterpriseBadge /> <EnterpriseBadge />
</Badges> </Badges>
</div> </div>
<div> <div>
<Header <Header
title="Browser Only Connections" title="TLS"
secondary secondary
description="Block all workspace access via SSH, port forward, and other non-browser connections." description="Ensure TLS is properly configured for your Coder deployment."
docsHref="https://coder.com/docs/coder-oss/latest/networking#browser-only-connections-enterprise" />
/>
<Badges> <OptionsTable
{entitlementsState.context.entitlements.features[ options={{
FeatureNames.BrowserOnly tls_enable: deploymentFlags.tls_enable,
].enabled ? ( tls_cert_files: deploymentFlags.tls_cert_files,
<EnabledBadge /> tls_key_files: deploymentFlags.tls_key_files,
) : ( tls_min_version: deploymentFlags.tls_min_version,
<DisabledBadge /> }}
)} />
<EnterpriseBadge /> </div>
</Badges> </Stack>
</div> </>
<div>
<Header
title="TLS"
secondary
description="Ensure TLS is properly configured for your Coder deployment."
/>
<TableContainer>
<Table>
<TableHead>
<TableRow>
<TableCell width="50%">Option</TableCell>
<TableCell width="50%">Value</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>
<OptionName>{deploymentFlags.tls_enable.name}</OptionName>
<OptionDescription>
{deploymentFlags.tls_enable.description}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>
{deploymentFlags.tls_enable.value ? (
<EnabledBadge />
) : (
<DisabledBadge />
)}
</OptionValue>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<OptionName>{deploymentFlags.tls_cert_files.name}</OptionName>
<OptionDescription>
{deploymentFlags.tls_cert_files.description}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>
<ul>
{deploymentFlags.tls_cert_files.value.map(
(file, index) => (
<li key={index}>{file}</li>
),
)}
</ul>
</OptionValue>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<OptionName>{deploymentFlags.tls_key_files.name}</OptionName>
<OptionDescription>
{deploymentFlags.tls_key_files.description}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>
<ul>
{deploymentFlags.tls_key_files.value.map(
(file, index) => (
<li key={index}>{file}</li>
),
)}
</ul>
</OptionValue>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<OptionName>
{deploymentFlags.tls_min_version.name}
</OptionName>
<OptionDescription>
{deploymentFlags.tls_min_version.description}
</OptionDescription>
</TableCell>
<TableCell>
<OptionValue>
{deploymentFlags.tls_min_version.value}
</OptionValue>
</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
</div>
</Stack>
) )
} }