From 331f8a46618be2439164439828593756c6f8e332 Mon Sep 17 00:00:00 2001 From: McKayla Washburn Date: Wed, 24 Apr 2024 18:52:51 +0000 Subject: [PATCH 1/9] feat: specify a custom terms of service link --- coderd/userauth.go | 3 ++- codersdk/deployment.go | 9 +++++++++ codersdk/users.go | 7 ++++--- site/src/api/typesGenerated.ts | 2 ++ site/src/pages/LoginPage/LoginPageView.stories.tsx | 8 ++++++++ site/src/pages/LoginPage/SignInForm.tsx | 14 ++++++++++++++ .../SecurityPage/SingleSignOnSection.tsx | 5 +---- site/src/testHelpers/entities.ts | 7 +++++++ 8 files changed, 47 insertions(+), 8 deletions(-) diff --git a/coderd/userauth.go b/coderd/userauth.go index eda4dd60abfa2..edbcd041882d7 100644 --- a/coderd/userauth.go +++ b/coderd/userauth.go @@ -472,6 +472,7 @@ func (api *API) userAuthMethods(rw http.ResponseWriter, r *http.Request) { } httpapi.Write(r.Context(), rw, http.StatusOK, codersdk.AuthMethods{ + TermsOfServiceLink: api.DeploymentValues.TermsOfServiceLink.Value(), Password: codersdk.AuthMethod{ Enabled: !api.DeploymentValues.DisablePasswordAuth.Value(), }, @@ -486,7 +487,7 @@ func (api *API) userAuthMethods(rw http.ResponseWriter, r *http.Request) { // @Summary OAuth 2.0 GitHub Callback // @ID oauth-20-github-callback -// @Security CoderSessionToken +// @Security CoderSessionTokens // @Tags Users // @Success 307 // @Router /users/oauth2/github/callback [get] diff --git a/codersdk/deployment.go b/codersdk/deployment.go index 34eaa4edd4c40..f5ef1182207cf 100644 --- a/codersdk/deployment.go +++ b/codersdk/deployment.go @@ -200,6 +200,7 @@ type DeploymentValues struct { AllowWorkspaceRenames serpent.Bool `json:"allow_workspace_renames,omitempty" typescript:",notnull"` Healthcheck HealthcheckConfig `json:"healthcheck,omitempty" typescript:",notnull"` CLIUpgradeMessage serpent.String `json:"cli_upgrade_message,omitempty" typescript:",notnull"` + TermsOfServiceLink serpent.String `json:"terms_of_service_link,omitempty" typescript:",notnull"` Config serpent.YAMLConfigPath `json:"config,omitempty" typescript:",notnull"` WriteConfig serpent.Bool `json:"write_config,omitempty" typescript:",notnull"` @@ -1683,6 +1684,14 @@ when required by your organization's security policy.`, YAML: "secureAuthCookie", Annotations: serpent.Annotations{}.Mark(annotationExternalProxies, "true"), }, + { + Name: "Terms of Service Link", + Description: "A link to an external Terms of Service that must be accepted by users when logging in.", + Flag: "terms-of-service-link", + Env: "CODER_TERMS_OF_SERVICE_LINK", + YAML: "termsOfServiceLink", + Value: &c.TermsOfServiceLink, + }, { Name: "Strict-Transport-Security", Description: "Controls if the 'Strict-Transport-Security' header is set on all static file responses. " + diff --git a/codersdk/users.go b/codersdk/users.go index 9fe6d8eb6552c..c82384e6164fc 100644 --- a/codersdk/users.go +++ b/codersdk/users.go @@ -209,9 +209,10 @@ type CreateOrganizationRequest struct { // AuthMethods contains authentication method information like whether they are enabled or not or custom text, etc. type AuthMethods struct { - Password AuthMethod `json:"password"` - Github AuthMethod `json:"github"` - OIDC OIDCAuthMethod `json:"oidc"` + TermsOfServiceLink string `json:"terms_of_service_link,omitempty"` + Password AuthMethod `json:"password"` + Github AuthMethod `json:"github"` + OIDC OIDCAuthMethod `json:"oidc"` } type AuthMethod struct { diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 13971a03457fb..3aae3ba8d22af 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -124,6 +124,7 @@ export interface AuthMethod { // From codersdk/users.go export interface AuthMethods { + readonly terms_of_service_link?: string; readonly password: AuthMethod; readonly github: AuthMethod; readonly oidc: OIDCAuthMethod; @@ -445,6 +446,7 @@ export interface DeploymentValues { readonly allow_workspace_renames?: boolean; readonly healthcheck?: HealthcheckConfig; readonly cli_upgrade_message?: string; + readonly terms_of_service_link?: string; readonly config?: string; readonly write_config?: boolean; readonly address?: string; diff --git a/site/src/pages/LoginPage/LoginPageView.stories.tsx b/site/src/pages/LoginPage/LoginPageView.stories.tsx index 48ea6e31d73f9..b7608e96adba7 100644 --- a/site/src/pages/LoginPage/LoginPageView.stories.tsx +++ b/site/src/pages/LoginPage/LoginPageView.stories.tsx @@ -3,6 +3,7 @@ import { MockAuthMethodsAll, MockAuthMethodsExternal, MockAuthMethodsPasswordOnly, + MockAuthMethodsPasswordTermsOfService, mockApiError, } from "testHelpers/entities"; import { LoginPageView } from "./LoginPageView"; @@ -33,6 +34,12 @@ export const WithAllAuthMethods: Story = { }, }; +export const WithTermsOfService: Story = { + args: { + authMethods: MockAuthMethodsPasswordTermsOfService, + }, +}; + export const AuthError: Story = { args: { error: mockApiError({ @@ -53,6 +60,7 @@ export const ExternalAuthError: Story = { export const LoadingAuthMethods: Story = { args: { + isLoading: true, authMethods: undefined, }, }; diff --git a/site/src/pages/LoginPage/SignInForm.tsx b/site/src/pages/LoginPage/SignInForm.tsx index 4efc0fbf7adfd..0f2a638a81746 100644 --- a/site/src/pages/LoginPage/SignInForm.tsx +++ b/site/src/pages/LoginPage/SignInForm.tsx @@ -1,4 +1,5 @@ import type { Interpolation, Theme } from "@emotion/react"; +import Checkbox from "@mui/material/Checkbox"; import type { FC, ReactNode } from "react"; import type { AuthMethods } from "api/typesGenerated"; import { Alert } from "components/Alert/Alert"; @@ -6,6 +7,7 @@ import { ErrorAlert } from "components/Alert/ErrorAlert"; import { getApplicationName } from "utils/appearance"; import { OAuthSignInForm } from "./OAuthSignInForm"; import { PasswordSignInForm } from "./PasswordSignInForm"; +import { Link } from "@mui/material"; export const Language = { emailLabel: "Email", @@ -123,6 +125,18 @@ export const SignInForm: FC = ({ /> )} + {authMethods?.terms_of_service_link && ( +
+ +
+ )} + {!passwordEnabled && !oAuthEnabled && ( No authentication methods configured! )} diff --git a/site/src/pages/UserSettingsPage/SecurityPage/SingleSignOnSection.tsx b/site/src/pages/UserSettingsPage/SecurityPage/SingleSignOnSection.tsx index 6d743594a9c0a..f2c14dcd45762 100644 --- a/site/src/pages/UserSettingsPage/SecurityPage/SingleSignOnSection.tsx +++ b/site/src/pages/UserSettingsPage/SecurityPage/SingleSignOnSection.tsx @@ -136,10 +136,7 @@ export const SingleSignOnSection: FC = ({ }) => { const theme = useTheme(); - const authList = Object.values( - authMethods, - ) as (typeof authMethods)[keyof typeof authMethods][]; - const noSsoEnabled = !authList.some((method) => method.enabled); + const noSsoEnabled = !authMethods.github.enabled && !authMethods.oidc.enabled; return ( <> diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index 3d9f837ab333b..4eeb6ad55f0d9 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -1373,6 +1373,13 @@ export const MockAuthMethodsPasswordOnly: TypesGen.AuthMethods = { oidc: { enabled: false, signInText: "", iconUrl: "" }, }; +export const MockAuthMethodsPasswordTermsOfService: TypesGen.AuthMethods = { + terms_of_service_link: "https://www.youtube.com/watch?v=C2f37Vb2NAE", + password: { enabled: true }, + github: { enabled: false }, + oidc: { enabled: false, signInText: "", iconUrl: "" }, +}; + export const MockAuthMethodsExternal: TypesGen.AuthMethods = { password: { enabled: false }, github: { enabled: true }, From 8f03a45404a3d1b048ee274cbda17c812de88744 Mon Sep 17 00:00:00 2001 From: McKayla Washburn Date: Wed, 24 Apr 2024 19:03:49 +0000 Subject: [PATCH 2/9] require check --- site/src/pages/LoginPage/SignInForm.tsx | 57 +++++++++++++++---------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/site/src/pages/LoginPage/SignInForm.tsx b/site/src/pages/LoginPage/SignInForm.tsx index 0f2a638a81746..2679404ede5c2 100644 --- a/site/src/pages/LoginPage/SignInForm.tsx +++ b/site/src/pages/LoginPage/SignInForm.tsx @@ -1,6 +1,6 @@ import type { Interpolation, Theme } from "@emotion/react"; import Checkbox from "@mui/material/Checkbox"; -import type { FC, ReactNode } from "react"; +import { type FC, type ReactNode, useState } from "react"; import type { AuthMethods } from "api/typesGenerated"; import { Alert } from "components/Alert/Alert"; import { ErrorAlert } from "components/Alert/ErrorAlert"; @@ -85,6 +85,10 @@ export const SignInForm: FC = ({ const passwordEnabled = authMethods?.password.enabled ?? true; const applicationName = getApplicationName(); + const [tosAccepted, setTosAccepted] = useState(false); + const termsOfServiceAcceptanceRequired = + authMethods?.terms_of_service_link && !tosAccepted; + return (

{applicationName}

@@ -101,34 +105,43 @@ export const SignInForm: FC = ({
)} - {oAuthEnabled && ( - - )} + {!termsOfServiceAcceptanceRequired && ( + <> + {oAuthEnabled && ( + + )} - {passwordEnabled && oAuthEnabled && ( -
-
-
Or
-
-
- )} + {passwordEnabled && oAuthEnabled && ( +
+
+
or
+
+
+ )} - {passwordEnabled && ( - + {passwordEnabled && ( + + )} + )} {authMethods?.terms_of_service_link && (
{buildInfo?.version}
+ + {authMethods?.terms_of_service_link && ( +
+ By continuing, you agree to the{" "} + + Terms of Service + + . +
+ )}
diff --git a/site/src/pages/LoginPage/SignInForm.tsx b/site/src/pages/LoginPage/SignInForm.tsx index 545fda48d787c..40930fd023a85 100644 --- a/site/src/pages/LoginPage/SignInForm.tsx +++ b/site/src/pages/LoginPage/SignInForm.tsx @@ -1,13 +1,11 @@ import type { Interpolation, Theme } from "@emotion/react"; -import Checkbox from "@mui/material/Checkbox"; -import { type FC, type ReactNode, useState } from "react"; +import type { FC, ReactNode } from "react"; import type { AuthMethods } from "api/typesGenerated"; import { Alert } from "components/Alert/Alert"; import { ErrorAlert } from "components/Alert/ErrorAlert"; import { getApplicationName } from "utils/appearance"; import { OAuthSignInForm } from "./OAuthSignInForm"; import { PasswordSignInForm } from "./PasswordSignInForm"; -import { Link } from "@mui/material"; export const Language = { emailLabel: "Email", @@ -85,10 +83,6 @@ export const SignInForm: FC = ({ const passwordEnabled = authMethods?.password.enabled ?? true; const applicationName = getApplicationName(); - const [tosAccepted, setTosAccepted] = useState(false); - const termsOfServiceAcceptanceRequired = - authMethods?.terms_of_service_link && !tosAccepted; - return (

{applicationName}

@@ -105,55 +99,30 @@ export const SignInForm: FC = ({
)} - {!termsOfServiceAcceptanceRequired && ( - <> - {oAuthEnabled && ( - - )} - - {passwordEnabled && oAuthEnabled && ( -
-
-
or
-
-
- )} - - {passwordEnabled && ( - - )} - + {oAuthEnabled && ( + )} - {authMethods?.terms_of_service_link && ( -
- + {passwordEnabled && oAuthEnabled && ( +
+
+
or
+
)} + {passwordEnabled && ( + + )} + {!passwordEnabled && !oAuthEnabled && ( No authentication methods configured! )} From 107d355e662040d310958a7faf44d138fd5c50c6 Mon Sep 17 00:00:00 2001 From: McKayla Washburn Date: Thu, 25 Apr 2024 18:53:49 +0000 Subject: [PATCH 5/9] tweaks --- site/src/pages/LoginPage/LoginPageView.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/site/src/pages/LoginPage/LoginPageView.tsx b/site/src/pages/LoginPage/LoginPageView.tsx index 3e9a1a337af4b..5d4ffc885c1f2 100644 --- a/site/src/pages/LoginPage/LoginPageView.tsx +++ b/site/src/pages/LoginPage/LoginPageView.tsx @@ -1,4 +1,5 @@ import type { Interpolation, Theme } from "@emotion/react"; +import LaunchIcon from "@mui/icons-material/LaunchOutlined"; import Link from "@mui/material/Link"; import type { FC } from "react"; import { useLocation } from "react-router-dom"; @@ -76,13 +77,14 @@ export const LoginPageView: FC = ({
By continuing, you agree to the{" "} - Terms of Service + Terms of Service  + - .
)} From 1d3c010190b2abf1642471b508bed5655bff0d7e Mon Sep 17 00:00:00 2001 From: McKayla Washburn Date: Thu, 25 Apr 2024 19:11:00 +0000 Subject: [PATCH 6/9] `make gen` --- coderd/apidoc/docs.go | 6 ++++++ coderd/apidoc/swagger.json | 6 ++++++ coderd/userauth.go | 2 +- docs/api/general.md | 1 + docs/api/schemas.md | 17 +++++++++++------ docs/api/users.md | 3 ++- docs/cli/server.md | 10 ++++++++++ 7 files changed, 37 insertions(+), 8 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 60ed16632c574..06e32af5df955 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -8446,6 +8446,9 @@ const docTemplate = `{ }, "password": { "$ref": "#/definitions/codersdk.AuthMethod" + }, + "terms_of_service_link": { + "type": "string" } } }, @@ -9408,6 +9411,9 @@ const docTemplate = `{ "telemetry": { "$ref": "#/definitions/codersdk.TelemetryConfig" }, + "terms_of_service_link": { + "type": "string" + }, "tls": { "$ref": "#/definitions/codersdk.TLSConfig" }, diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 785450be71cdb..2ca0aa31332b1 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -7515,6 +7515,9 @@ }, "password": { "$ref": "#/definitions/codersdk.AuthMethod" + }, + "terms_of_service_link": { + "type": "string" } } }, @@ -8413,6 +8416,9 @@ "telemetry": { "$ref": "#/definitions/codersdk.TelemetryConfig" }, + "terms_of_service_link": { + "type": "string" + }, "tls": { "$ref": "#/definitions/codersdk.TLSConfig" }, diff --git a/coderd/userauth.go b/coderd/userauth.go index edbcd041882d7..9a1187c493027 100644 --- a/coderd/userauth.go +++ b/coderd/userauth.go @@ -487,7 +487,7 @@ func (api *API) userAuthMethods(rw http.ResponseWriter, r *http.Request) { // @Summary OAuth 2.0 GitHub Callback // @ID oauth-20-github-callback -// @Security CoderSessionTokens +// @Security CoderSessionToken // @Tags Users // @Success 307 // @Router /users/oauth2/github/callback [get] diff --git a/docs/api/general.md b/docs/api/general.md index 330c41a335b9b..235e6a3b5a442 100644 --- a/docs/api/general.md +++ b/docs/api/general.md @@ -377,6 +377,7 @@ curl -X GET http://coder-server:8080/api/v2/deployment/config \ "user": {} } }, + "terms_of_service_link": "string", "tls": { "address": { "host": "string", diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 1d00ac18c3586..3b9c95ac90864 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -1040,17 +1040,19 @@ }, "password": { "enabled": true - } + }, + "terms_of_service_link": "string" } ``` ### Properties -| Name | Type | Required | Restrictions | Description | -| ---------- | -------------------------------------------------- | -------- | ------------ | ----------- | -| `github` | [codersdk.AuthMethod](#codersdkauthmethod) | false | | | -| `oidc` | [codersdk.OIDCAuthMethod](#codersdkoidcauthmethod) | false | | | -| `password` | [codersdk.AuthMethod](#codersdkauthmethod) | false | | | +| Name | Type | Required | Restrictions | Description | +| ----------------------- | -------------------------------------------------- | -------- | ------------ | ----------- | +| `github` | [codersdk.AuthMethod](#codersdkauthmethod) | false | | | +| `oidc` | [codersdk.OIDCAuthMethod](#codersdkoidcauthmethod) | false | | | +| `password` | [codersdk.AuthMethod](#codersdkauthmethod) | false | | | +| `terms_of_service_link` | string | false | | | ## codersdk.AuthorizationCheck @@ -2102,6 +2104,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o "user": {} } }, + "terms_of_service_link": "string", "tls": { "address": { "host": "string", @@ -2474,6 +2477,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o "user": {} } }, + "terms_of_service_link": "string", "tls": { "address": { "host": "string", @@ -2562,6 +2566,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o | `support` | [codersdk.SupportConfig](#codersdksupportconfig) | false | | | | `swagger` | [codersdk.SwaggerConfig](#codersdkswaggerconfig) | false | | | | `telemetry` | [codersdk.TelemetryConfig](#codersdktelemetryconfig) | false | | | +| `terms_of_service_link` | string | false | | | | `tls` | [codersdk.TLSConfig](#codersdktlsconfig) | false | | | | `trace` | [codersdk.TraceConfig](#codersdktraceconfig) | false | | | | `update_check` | boolean | false | | | diff --git a/docs/api/users.md b/docs/api/users.md index a057376b38f16..70c07ff53ed0d 100644 --- a/docs/api/users.md +++ b/docs/api/users.md @@ -157,7 +157,8 @@ curl -X GET http://coder-server:8080/api/v2/users/authmethods \ }, "password": { "enabled": true - } + }, + "terms_of_service_link": "string" } ``` diff --git a/docs/cli/server.md b/docs/cli/server.md index 2a793c6faf0a5..cb6c8756c93b1 100644 --- a/docs/cli/server.md +++ b/docs/cli/server.md @@ -928,6 +928,16 @@ Type of auth to use when connecting to postgres. Controls if the 'Secure' property is set on browser session cookies. +### --terms-of-service-link + +| | | +| ----------- | ----------------------------------------- | +| Type | string | +| Environment | $CODER_TERMS_OF_SERVICE_LINK | +| YAML | termsOfServiceLink | + +A link to an external Terms of Service that must be accepted by users when logging in. + ### --strict-transport-security | | | From e8550dcfd0370848d6309536434b708d1a41c0f0 Mon Sep 17 00:00:00 2001 From: McKayla Washburn Date: Thu, 25 Apr 2024 19:23:59 +0000 Subject: [PATCH 7/9] url --- coderd/apidoc/docs.go | 4 ++-- coderd/apidoc/swagger.json | 4 ++-- coderd/userauth.go | 2 +- codersdk/deployment.go | 14 +++++++------- codersdk/users.go | 8 ++++---- docs/api/general.md | 2 +- docs/api/schemas.md | 20 ++++++++++---------- docs/api/users.md | 2 +- docs/cli/server.md | 14 +++++++------- site/src/api/typesGenerated.ts | 4 ++-- site/src/pages/LoginPage/LoginPageView.tsx | 4 ++-- site/src/testHelpers/entities.ts | 2 +- 12 files changed, 40 insertions(+), 40 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 06e32af5df955..a87ee28027f3e 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -8447,7 +8447,7 @@ const docTemplate = `{ "password": { "$ref": "#/definitions/codersdk.AuthMethod" }, - "terms_of_service_link": { + "terms_of_service_url": { "type": "string" } } @@ -9411,7 +9411,7 @@ const docTemplate = `{ "telemetry": { "$ref": "#/definitions/codersdk.TelemetryConfig" }, - "terms_of_service_link": { + "terms_of_service_url": { "type": "string" }, "tls": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 2ca0aa31332b1..7d03086d55997 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -7516,7 +7516,7 @@ "password": { "$ref": "#/definitions/codersdk.AuthMethod" }, - "terms_of_service_link": { + "terms_of_service_url": { "type": "string" } } @@ -8416,7 +8416,7 @@ "telemetry": { "$ref": "#/definitions/codersdk.TelemetryConfig" }, - "terms_of_service_link": { + "terms_of_service_url": { "type": "string" }, "tls": { diff --git a/coderd/userauth.go b/coderd/userauth.go index 9a1187c493027..3f341db65bcb1 100644 --- a/coderd/userauth.go +++ b/coderd/userauth.go @@ -472,7 +472,7 @@ func (api *API) userAuthMethods(rw http.ResponseWriter, r *http.Request) { } httpapi.Write(r.Context(), rw, http.StatusOK, codersdk.AuthMethods{ - TermsOfServiceLink: api.DeploymentValues.TermsOfServiceLink.Value(), + TermsOfServiceURL: api.DeploymentValues.TermsOfServiceURL.Value(), Password: codersdk.AuthMethod{ Enabled: !api.DeploymentValues.DisablePasswordAuth.Value(), }, diff --git a/codersdk/deployment.go b/codersdk/deployment.go index f5ef1182207cf..d2da0c3183333 100644 --- a/codersdk/deployment.go +++ b/codersdk/deployment.go @@ -200,7 +200,7 @@ type DeploymentValues struct { AllowWorkspaceRenames serpent.Bool `json:"allow_workspace_renames,omitempty" typescript:",notnull"` Healthcheck HealthcheckConfig `json:"healthcheck,omitempty" typescript:",notnull"` CLIUpgradeMessage serpent.String `json:"cli_upgrade_message,omitempty" typescript:",notnull"` - TermsOfServiceLink serpent.String `json:"terms_of_service_link,omitempty" typescript:",notnull"` + TermsOfServiceURL serpent.String `json:"terms_of_service_url,omitempty" typescript:",notnull"` Config serpent.YAMLConfigPath `json:"config,omitempty" typescript:",notnull"` WriteConfig serpent.Bool `json:"write_config,omitempty" typescript:",notnull"` @@ -1685,12 +1685,12 @@ when required by your organization's security policy.`, Annotations: serpent.Annotations{}.Mark(annotationExternalProxies, "true"), }, { - Name: "Terms of Service Link", - Description: "A link to an external Terms of Service that must be accepted by users when logging in.", - Flag: "terms-of-service-link", - Env: "CODER_TERMS_OF_SERVICE_LINK", - YAML: "termsOfServiceLink", - Value: &c.TermsOfServiceLink, + Name: "Terms of Service URL", + Description: "A URL to an external Terms of Service that must be accepted by users when logging in.", + Flag: "terms-of-service-url", + Env: "CODER_TERMS_OF_SERVICE_URL", + YAML: "termsOfServiceURL", + Value: &c.TermsOfServiceURL, }, { Name: "Strict-Transport-Security", diff --git a/codersdk/users.go b/codersdk/users.go index c82384e6164fc..7eb7604fc57b7 100644 --- a/codersdk/users.go +++ b/codersdk/users.go @@ -209,10 +209,10 @@ type CreateOrganizationRequest struct { // AuthMethods contains authentication method information like whether they are enabled or not or custom text, etc. type AuthMethods struct { - TermsOfServiceLink string `json:"terms_of_service_link,omitempty"` - Password AuthMethod `json:"password"` - Github AuthMethod `json:"github"` - OIDC OIDCAuthMethod `json:"oidc"` + TermsOfServiceURL string `json:"terms_of_service_url,omitempty"` + Password AuthMethod `json:"password"` + Github AuthMethod `json:"github"` + OIDC OIDCAuthMethod `json:"oidc"` } type AuthMethod struct { diff --git a/docs/api/general.md b/docs/api/general.md index 235e6a3b5a442..95b3933a9a89a 100644 --- a/docs/api/general.md +++ b/docs/api/general.md @@ -377,7 +377,7 @@ curl -X GET http://coder-server:8080/api/v2/deployment/config \ "user": {} } }, - "terms_of_service_link": "string", + "terms_of_service_url": "string", "tls": { "address": { "host": "string", diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 3b9c95ac90864..9f2a74752a156 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -1041,18 +1041,18 @@ "password": { "enabled": true }, - "terms_of_service_link": "string" + "terms_of_service_url": "string" } ``` ### Properties -| Name | Type | Required | Restrictions | Description | -| ----------------------- | -------------------------------------------------- | -------- | ------------ | ----------- | -| `github` | [codersdk.AuthMethod](#codersdkauthmethod) | false | | | -| `oidc` | [codersdk.OIDCAuthMethod](#codersdkoidcauthmethod) | false | | | -| `password` | [codersdk.AuthMethod](#codersdkauthmethod) | false | | | -| `terms_of_service_link` | string | false | | | +| Name | Type | Required | Restrictions | Description | +| ---------------------- | -------------------------------------------------- | -------- | ------------ | ----------- | +| `github` | [codersdk.AuthMethod](#codersdkauthmethod) | false | | | +| `oidc` | [codersdk.OIDCAuthMethod](#codersdkoidcauthmethod) | false | | | +| `password` | [codersdk.AuthMethod](#codersdkauthmethod) | false | | | +| `terms_of_service_url` | string | false | | | ## codersdk.AuthorizationCheck @@ -2104,7 +2104,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o "user": {} } }, - "terms_of_service_link": "string", + "terms_of_service_url": "string", "tls": { "address": { "host": "string", @@ -2477,7 +2477,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o "user": {} } }, - "terms_of_service_link": "string", + "terms_of_service_url": "string", "tls": { "address": { "host": "string", @@ -2566,7 +2566,7 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o | `support` | [codersdk.SupportConfig](#codersdksupportconfig) | false | | | | `swagger` | [codersdk.SwaggerConfig](#codersdkswaggerconfig) | false | | | | `telemetry` | [codersdk.TelemetryConfig](#codersdktelemetryconfig) | false | | | -| `terms_of_service_link` | string | false | | | +| `terms_of_service_url` | string | false | | | | `tls` | [codersdk.TLSConfig](#codersdktlsconfig) | false | | | | `trace` | [codersdk.TraceConfig](#codersdktraceconfig) | false | | | | `update_check` | boolean | false | | | diff --git a/docs/api/users.md b/docs/api/users.md index 70c07ff53ed0d..c9910bf66c1c7 100644 --- a/docs/api/users.md +++ b/docs/api/users.md @@ -158,7 +158,7 @@ curl -X GET http://coder-server:8080/api/v2/users/authmethods \ "password": { "enabled": true }, - "terms_of_service_link": "string" + "terms_of_service_url": "string" } ``` diff --git a/docs/cli/server.md b/docs/cli/server.md index cb6c8756c93b1..a7c32c2d78420 100644 --- a/docs/cli/server.md +++ b/docs/cli/server.md @@ -928,15 +928,15 @@ Type of auth to use when connecting to postgres. Controls if the 'Secure' property is set on browser session cookies. -### --terms-of-service-link +### --terms-of-service-url -| | | -| ----------- | ----------------------------------------- | -| Type | string | -| Environment | $CODER_TERMS_OF_SERVICE_LINK | -| YAML | termsOfServiceLink | +| | | +| ----------- | ---------------------------------------- | +| Type | string | +| Environment | $CODER_TERMS_OF_SERVICE_URL | +| YAML | termsOfServiceURL | -A link to an external Terms of Service that must be accepted by users when logging in. +A URL to an external Terms of Service that must be accepted by users when logging in. ### --strict-transport-security diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 3aae3ba8d22af..45062e910fa64 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -124,7 +124,7 @@ export interface AuthMethod { // From codersdk/users.go export interface AuthMethods { - readonly terms_of_service_link?: string; + readonly terms_of_service_url?: string; readonly password: AuthMethod; readonly github: AuthMethod; readonly oidc: OIDCAuthMethod; @@ -446,7 +446,7 @@ export interface DeploymentValues { readonly allow_workspace_renames?: boolean; readonly healthcheck?: HealthcheckConfig; readonly cli_upgrade_message?: string; - readonly terms_of_service_link?: string; + readonly terms_of_service_url?: string; readonly config?: string; readonly write_config?: boolean; readonly address?: string; diff --git a/site/src/pages/LoginPage/LoginPageView.tsx b/site/src/pages/LoginPage/LoginPageView.tsx index 5d4ffc885c1f2..620fa252531bd 100644 --- a/site/src/pages/LoginPage/LoginPageView.tsx +++ b/site/src/pages/LoginPage/LoginPageView.tsx @@ -73,12 +73,12 @@ export const LoginPageView: FC = ({
{buildInfo?.version}
- {authMethods?.terms_of_service_link && ( + {authMethods?.terms_of_service_url && (
By continuing, you agree to the{" "} diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index 4eeb6ad55f0d9..6604faf96eafd 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -1374,7 +1374,7 @@ export const MockAuthMethodsPasswordOnly: TypesGen.AuthMethods = { }; export const MockAuthMethodsPasswordTermsOfService: TypesGen.AuthMethods = { - terms_of_service_link: "https://www.youtube.com/watch?v=C2f37Vb2NAE", + terms_of_service_url: "https://www.youtube.com/watch?v=C2f37Vb2NAE", password: { enabled: true }, github: { enabled: false }, oidc: { enabled: false, signInText: "", iconUrl: "" }, From 43f20ea9bed88dc31f63aa49994a7a93231dd8ff Mon Sep 17 00:00:00 2001 From: McKayla Washburn Date: Thu, 25 Apr 2024 19:52:23 +0000 Subject: [PATCH 8/9] i like --- site/src/pages/LoginPage/LoginPageView.tsx | 34 +++++++++---------- .../pages/LoginPage/TermsOfServiceLink.tsx | 28 +++++++++++++++ 2 files changed, 45 insertions(+), 17 deletions(-) create mode 100644 site/src/pages/LoginPage/TermsOfServiceLink.tsx diff --git a/site/src/pages/LoginPage/LoginPageView.tsx b/site/src/pages/LoginPage/LoginPageView.tsx index 620fa252531bd..c2c369b7455bd 100644 --- a/site/src/pages/LoginPage/LoginPageView.tsx +++ b/site/src/pages/LoginPage/LoginPageView.tsx @@ -1,7 +1,6 @@ import type { Interpolation, Theme } from "@emotion/react"; -import LaunchIcon from "@mui/icons-material/LaunchOutlined"; -import Link from "@mui/material/Link"; -import type { FC } from "react"; +import Button from "@mui/material/Button"; +import { type FC, useState } from "react"; import { useLocation } from "react-router-dom"; import type { AuthMethods, BuildInfoResponse } from "api/typesGenerated"; import { CoderIcon } from "components/Icons/CoderIcon"; @@ -9,6 +8,7 @@ import { Loader } from "components/Loader/Loader"; import { getApplicationName, getLogoURL } from "utils/appearance"; import { retrieveRedirect } from "utils/redirect"; import { SignInForm } from "./SignInForm"; +import { TermsOfServiceLink } from "./TermsOfServiceLink"; export interface LoginPageViewProps { authMethods: AuthMethods | undefined; @@ -51,12 +51,21 @@ export const LoginPageView: FC = ({ ); + const [tosAccepted, setTosAccepted] = useState(false); + const tosAcceptanceRequired = + authMethods?.terms_of_service_url && !tosAccepted; + return (
{applicationLogo} {isLoading ? ( + ) : tosAcceptanceRequired ? ( + <> + + + ) : ( = ({ Copyright © {new Date().getFullYear()} Coder Technologies, Inc.
{buildInfo?.version}
- - {authMethods?.terms_of_service_url && ( -
- By continuing, you agree to the{" "} - - Terms of Service  - - -
+ {tosAccepted && ( + )}
diff --git a/site/src/pages/LoginPage/TermsOfServiceLink.tsx b/site/src/pages/LoginPage/TermsOfServiceLink.tsx new file mode 100644 index 0000000000000..6a2659b17b4d3 --- /dev/null +++ b/site/src/pages/LoginPage/TermsOfServiceLink.tsx @@ -0,0 +1,28 @@ +import LaunchIcon from "@mui/icons-material/LaunchOutlined"; +import Link from "@mui/material/Link"; +import type { FC } from "react"; + +interface TermsOfServiceLinkProps { + className?: string; + url?: string; +} + +export const TermsOfServiceLink: FC = ({ + className, + url, +}) => { + return ( +
+ By continuing, you agree to the{" "} + + Terms of Service  + + +
+ ); +}; From a06ddc2271f998f550194fc998141f5a3b0b38c6 Mon Sep 17 00:00:00 2001 From: McKayla Washburn Date: Thu, 25 Apr 2024 19:58:36 +0000 Subject: [PATCH 9/9] `make update-golden-files` --- cli/testdata/coder_server_--help.golden | 4 ++++ cli/testdata/server-config.yaml.golden | 4 ++++ enterprise/cli/testdata/coder_server_--help.golden | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/cli/testdata/coder_server_--help.golden b/cli/testdata/coder_server_--help.golden index f7ba3b2f801ca..6d8f866c11c0b 100644 --- a/cli/testdata/coder_server_--help.golden +++ b/cli/testdata/coder_server_--help.golden @@ -60,6 +60,10 @@ OPTIONS: --support-links struct[[]codersdk.LinkConfig], $CODER_SUPPORT_LINKS Support links to display in the top right drop down menu. + --terms-of-service-url string, $CODER_TERMS_OF_SERVICE_URL + A URL to an external Terms of Service that must be accepted by users + when logging in. + --update-check bool, $CODER_UPDATE_CHECK (default: false) Periodically check for new releases of Coder and inform the owner. The check is performed once per day. diff --git a/cli/testdata/server-config.yaml.golden b/cli/testdata/server-config.yaml.golden index f70d8b88257ee..4366dbc4d9677 100644 --- a/cli/testdata/server-config.yaml.golden +++ b/cli/testdata/server-config.yaml.golden @@ -414,6 +414,10 @@ inMemoryDatabase: false # Type of auth to use when connecting to postgres. # (default: password, type: enum[password\|awsiamrds]) pgAuth: password +# A URL to an external Terms of Service that must be accepted by users when +# logging in. +# (default: , type: string) +termsOfServiceURL: "" # The algorithm to use for generating ssh keys. Accepted values are "ed25519", # "ecdsa", or "rsa4096". # (default: ed25519, type: string) diff --git a/enterprise/cli/testdata/coder_server_--help.golden b/enterprise/cli/testdata/coder_server_--help.golden index 50dfa3bdd4785..4d4576d6d57cc 100644 --- a/enterprise/cli/testdata/coder_server_--help.golden +++ b/enterprise/cli/testdata/coder_server_--help.golden @@ -61,6 +61,10 @@ OPTIONS: --support-links struct[[]codersdk.LinkConfig], $CODER_SUPPORT_LINKS Support links to display in the top right drop down menu. + --terms-of-service-url string, $CODER_TERMS_OF_SERVICE_URL + A URL to an external Terms of Service that must be accepted by users + when logging in. + --update-check bool, $CODER_UPDATE_CHECK (default: false) Periodically check for new releases of Coder and inform the owner. The check is performed once per day.