From 464841de2ae8f2a5f2bf51b065cb9806e181daa7 Mon Sep 17 00:00:00 2001 From: Antoine Jaussoin Date: Fri, 25 Mar 2022 19:32:45 +0000 Subject: [PATCH] Optional setting to disable Anonymous accounts (on Self-Hosted instances) (#377) --- .env.example | 1 + README.md | 1 + backend/src/admin/router.ts | 1 + backend/src/auth/passport.ts | 9 ++++++++- backend/src/common/payloads.ts | 1 + backend/src/config.ts | 1 + backend/src/types.ts | 1 + docs/docs/self-hosting/optionals.md | 1 + frontend/src/auth/modal/LoginModal.tsx | 14 +++++++++----- frontend/src/common/payloads.ts | 1 + frontend/src/global/state.ts | 1 + self-hosting/docker-compose.full.yml | 1 + 12 files changed, 27 insertions(+), 6 deletions(-) diff --git a/.env.example b/.env.example index 22780e8ca..c7d27b974 100644 --- a/.env.example +++ b/.env.example @@ -13,6 +13,7 @@ SELF_HOSTED=false SELF_HOSTED_ADMIN=admin@admin.org SENTRY_URL= SESSION_SECRET=changeme +DISABLE_ANONYMOUS_LOGIN=false TWITTER_KEY= TWITTER_SECRET= GOOGLE_KEY= diff --git a/README.md b/README.md index 623fd803f..284462b69 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,7 @@ This will run a demo version, which you can turn into a fully licenced version b - Update prices, especially for USD - Make the integration tests less brittle by using specific attributes - Upgrade (finally!) to React-Router v6. +- Self-Hosting: Allow an administrator to disable Anonymous Logins (to force users to use regular accounts). ### Version 4.12.1 (hotfix) diff --git a/backend/src/admin/router.ts b/backend/src/admin/router.ts index 3e9711945..e110da923 100644 --- a/backend/src/admin/router.ts +++ b/backend/src/admin/router.ts @@ -24,6 +24,7 @@ router.get('/self-hosting', async (_, res) => { !!config.SENDGRID_RESET_PASSWORD_TID && !!config.SENDGRID_VERIFICATION_EMAIL_TID && !!config.SENDGRID_SENDER, + disableAnonymous: config.DISABLE_ANONYMOUS_LOGIN, oAuth: { google: !!config.GOOGLE_KEY && !!config.GOOGLE_SECRET, github: !!config.GITHUB_KEY && !!config.GITHUB_SECRET, diff --git a/backend/src/auth/passport.ts b/backend/src/auth/passport.ts index 7cd57fd93..cf878cccc 100644 --- a/backend/src/auth/passport.ts +++ b/backend/src/auth/passport.ts @@ -30,6 +30,7 @@ import { } from './types'; import { registerUser, UserRegistration } from '../db/actions/users'; import { serialiseIds, UserIds, deserialiseIds } from '../utils'; +import config from '../config'; export default () => { passport.serializeUser((user, cb) => { @@ -242,7 +243,13 @@ export default () => { username.startsWith('ANONUSER__') && username.endsWith('__ANONUSER') ) { - // Anonymouns login + // Anonymous login + + // Checking if they are allowed in the first place + if (config.DISABLE_ANONYMOUS_LOGIN) { + return done('Anonymous accounts are disabled', undefined); + } + const actualUsername = username .replace('ANONUSER__', '') .replace('__ANONUSER', ''); diff --git a/backend/src/common/payloads.ts b/backend/src/common/payloads.ts index 9fdf11fec..f533390c4 100644 --- a/backend/src/common/payloads.ts +++ b/backend/src/common/payloads.ts @@ -57,6 +57,7 @@ export interface BackendCapabilities { adminEmail: string; licenced: boolean; oAuth: OAuthAvailabilities; + disableAnonymous: boolean; } export interface OAuthAvailabilities { diff --git a/backend/src/config.ts b/backend/src/config.ts index 94b5dff19..a81b117e8 100644 --- a/backend/src/config.ts +++ b/backend/src/config.ts @@ -64,6 +64,7 @@ const config: BackendConfig = { SENTRY_URL: defaults('SENTRY_URL', ''), BASE_URL: defaults('BASE_URL', 'http://localhost:80'), SECURE_COOKIES: defaultsBool('SECURE_COOKIES', false), + DISABLE_ANONYMOUS_LOGIN: defaultsBool('DISABLE_ANONYMOUS_LOGIN', false), TWITTER_KEY: defaults('TWITTER_KEY', ''), TWITTER_SECRET: defaults('TWITTER_SECRET', ''), GOOGLE_KEY: defaults('GOOGLE_KEY', ''), diff --git a/backend/src/types.ts b/backend/src/types.ts index 3cb786b09..e49cba114 100644 --- a/backend/src/types.ts +++ b/backend/src/types.ts @@ -17,6 +17,7 @@ export interface BackendConfig { BASE_URL: string; SECURE_COOKIES: boolean; SENTRY_URL: string; + DISABLE_ANONYMOUS_LOGIN: boolean; TWITTER_KEY: string; TWITTER_SECRET: string; GOOGLE_KEY: string; diff --git a/docs/docs/self-hosting/optionals.md b/docs/docs/self-hosting/optionals.md index 4265ce097..331738d49 100644 --- a/docs/docs/self-hosting/optionals.md +++ b/docs/docs/self-hosting/optionals.md @@ -39,6 +39,7 @@ services: SENTRY_URL: '' # Optional, Sentry URL (https://1234567890abcdef12345@sentry.io/1234567) BASE_URL: http://localhost:80 # This must be the URL of the frontend app once deployed. Only useful if you need OAuth, SendGrid or Stripe SECURE_COOKIES: 'false' # You can set this to true if you are using HTTPS. This is more secure. + DISABLE_ANONYMOUS_LOGIN: 'false' # Set to true to disable anonymous accounts # -- OAuth: Set these to enable OAuth authentication for one or more provider. This is optional. -- TWITTER_KEY: diff --git a/frontend/src/auth/modal/LoginModal.tsx b/frontend/src/auth/modal/LoginModal.tsx index ad206185c..f40d15b63 100644 --- a/frontend/src/auth/modal/LoginModal.tsx +++ b/frontend/src/auth/modal/LoginModal.tsx @@ -11,6 +11,7 @@ import SocialAuth from './SocialAuth'; import AnonAuth from './AnonAuth'; import AccountAuth from './AccountAuth'; import useOAuthAvailabilities from '../../global/useOAuthAvailabilities'; +import useBackendCapabilities from '../../global/useBackendCapabilities'; interface LoginModalProps { onClose: () => void; @@ -18,6 +19,7 @@ interface LoginModalProps { const Login = ({ onClose }: LoginModalProps) => { const { any } = useOAuthAvailabilities(); + const { disableAnonymous } = useBackendCapabilities(); const hasNoSocialMediaAuth = !any; const translations = useTranslations(); const fullScreen = useMediaQuery('(max-width:600px)'); @@ -64,11 +66,13 @@ const Login = ({ onClose }: LoginModalProps) => { value="account" data-cy="account-tab" /> - + {!disableAnonymous ? ( + + ) : null} diff --git a/frontend/src/common/payloads.ts b/frontend/src/common/payloads.ts index 9fdf11fec..f533390c4 100644 --- a/frontend/src/common/payloads.ts +++ b/frontend/src/common/payloads.ts @@ -57,6 +57,7 @@ export interface BackendCapabilities { adminEmail: string; licenced: boolean; oAuth: OAuthAvailabilities; + disableAnonymous: boolean; } export interface OAuthAvailabilities { diff --git a/frontend/src/global/state.ts b/frontend/src/global/state.ts index 070a572cf..15351ecc6 100644 --- a/frontend/src/global/state.ts +++ b/frontend/src/global/state.ts @@ -7,6 +7,7 @@ export const backendCapabilitiesState = atom({ adminEmail: '', licenced: true, selfHosted: false, + disableAnonymous: false, oAuth: { google: false, github: false, diff --git a/self-hosting/docker-compose.full.yml b/self-hosting/docker-compose.full.yml index a21accd91..ad21440a9 100644 --- a/self-hosting/docker-compose.full.yml +++ b/self-hosting/docker-compose.full.yml @@ -67,6 +67,7 @@ services: SENTRY_URL: '' # Optional, Sentry URL (https://1234567890abcdef12345@sentry.io/1234567) BASE_URL: http://localhost:80 # This must be the URL of the frontend app once deployed. Only useful if you need OAuth, SendGrid or Stripe SECURE_COOKIES: 'false' # You can set this to true if you are using HTTPS. This is more secure. + DISABLE_ANONYMOUS_LOGIN: 'false' # Set to true to disable anonymous accounts # -- OAuth: Set these to enable OAuth authentication for one or more provider. This is optional. -- TWITTER_KEY: