feat: account creation on/off toggling

This commit is contained in:
ae 2025-05-05 10:18:07 +03:00
parent dba81d65cb
commit 0ef65937e8
Signed by: ae
GPG Key ID: 995EFD5C1B532B3E
7 changed files with 76 additions and 60 deletions

View File

@ -10,11 +10,14 @@ JWT_SECRET=""
CSRF_SECRET="" # Should be 32 bytes long CSRF_SECRET="" # Should be 32 bytes long
ADMIN_USERNAME="" ADMIN_USERNAME=""
ADMIN_PASSWORD="" ADMIN_PASSWORD=""
ACCOUNT_CREATION_ENABLED="0"
LOG_LEVEL="info" LOG_LEVEL="info"
APP_ENV="production" APP_ENV="production"
DOMAIN="" DOMAIN=""
FRONTEND_URL="" FRONTEND_URL=""
# Frontend # Frontend (build-stage)
VITE_ACCOUNT_CREATION_ENABLED="$ACCOUNT_CREATION_ENABLED"
VITE_VIEW_COOKIE_PATH="/" VITE_VIEW_COOKIE_PATH="/"
VITE_COOKIE_SAME_SITE="strict" VITE_COOKIE_SAME_SITE="strict"
VITE_VIEW_COOKIE_DOMAIN="$DOMAIN"

View File

@ -37,6 +37,7 @@ services:
CSRF_SECRET: ${CSRF_SECRET:?csrf secret required} CSRF_SECRET: ${CSRF_SECRET:?csrf secret required}
ADMIN_USERNAME: ${ADMIN_USERNAME:?init admin username required} ADMIN_USERNAME: ${ADMIN_USERNAME:?init admin username required}
ADMIN_PASSWORD: ${ADMIN_PASSWORD:?init admin password required} ADMIN_PASSWORD: ${ADMIN_PASSWORD:?init admin password required}
ACCOUNT_CREATION_ENABLED: ${ACCOUNT_CREATION_ENABLED:-0}
LOG_LEVEL: debug LOG_LEVEL: debug
APP_ENV: development APP_ENV: development
DOMAIN: localhost DOMAIN: localhost

View File

@ -35,6 +35,7 @@ services:
CSRF_SECRET: ${CSRF_SECRET:?csrf secret required} CSRF_SECRET: ${CSRF_SECRET:?csrf secret required}
ADMIN_USERNAME: ${ADMIN_USERNAME:?init admin username required} ADMIN_USERNAME: ${ADMIN_USERNAME:?init admin username required}
ADMIN_PASSWORD: ${ADMIN_PASSWORD:?init admin password required} ADMIN_PASSWORD: ${ADMIN_PASSWORD:?init admin password required}
ACCOUNT_CREATION_ENABLED: ${ACCOUNT_CREATION_ENABLED:-0}
LOG_LEVEL: ${LOG_LEVEL:-info} LOG_LEVEL: ${LOG_LEVEL:-info}
APP_ENV: ${APP_ENV:-production} APP_ENV: ${APP_ENV:-production}
DOMAIN: ${DOMAIN:-localhost} DOMAIN: ${DOMAIN:-localhost}
@ -53,10 +54,6 @@ services:
- 3000:80 # Container port defined in nginx.conf (bound to 3000 for dev.) - 3000:80 # Container port defined in nginx.conf (bound to 3000 for dev.)
depends_on: depends_on:
- qnote-server - qnote-server
environment:
VITE_VIEW_COOKIE_PATH: ${VITE_VIEW_COOKIE_PATH:-/}
VITE_VIEW_COOKIE_DOMAIN: ${DOMAIN:-localhost}
VITE_COOKIE_SAME_SITE: ${VITE_COOKIE_SAME_SITE:-strict}
networks: networks:
qnote: qnote:

View File

@ -96,7 +96,9 @@ func (rs authResource) Routes() chi.Router {
r := chi.NewRouter() r := chi.NewRouter()
// Public routes (the only outside facing endpoints in the whole API with no requirement for auth) // Public routes (the only outside facing endpoints in the whole API with no requirement for auth)
if rs.Config.IsRegEnabled {
r.Post("/signup", rs.Create) // POST /auth/signup - registration (rate-limited) r.Post("/signup", rs.Create) // POST /auth/signup - registration (rate-limited)
}
r.Post("/login", rs.Login) // POST /auth/login - login (rate-limited) r.Post("/login", rs.Login) // POST /auth/login - login (rate-limited)
// Protected routes (access token required) // Protected routes (access token required)

View File

@ -20,6 +20,7 @@ type SvcConfig struct {
JWTSecret string JWTSecret string
CSRFSecret string CSRFSecret string
IsProd bool IsProd bool
IsRegEnabled bool
Domain string Domain string
FrontendURL string FrontendURL string
} }

View File

@ -31,14 +31,13 @@ type Config struct {
DatabaseURL string `env:"DB_URL,notEmpty"` DatabaseURL string `env:"DB_URL,notEmpty"`
AdminUsername string `env:"ADMIN_USERNAME,notEmpty,unset"` AdminUsername string `env:"ADMIN_USERNAME,notEmpty,unset"`
AdminPassword string `env:"ADMIN_PASSWORD,notEmpty,unset"` AdminPassword string `env:"ADMIN_PASSWORD,notEmpty,unset"`
AccountCreationEnabled bool `env:"ACCOUNT_CREATION_ENABLED" envDefault:"0"`
Domain string `env:"DOMAIN" envDefault:"localhost"` Domain string `env:"DOMAIN" envDefault:"localhost"`
FrontendURL string `env:"FRONTEND_URL" envDefault:"http://localhost:5173"` FrontendURL string `env:"FRONTEND_URL" envDefault:"http://localhost:5173"`
LogLevel string `env:"LOG_LEVEL" envDefault:"info"` LogLevel string `env:"LOG_LEVEL" envDefault:"info"`
AppEnv string `env:"APP_ENV" envDefault:"production"` AppEnv string `env:"APP_ENV" envDefault:"production"`
} }
// TODO: add flag to enable/disable registration of new users
func init() { func init() {
config = Config{} config = Config{}
if err := env.Parse(&config); err != nil { if err := env.Parse(&config); err != nil {
@ -50,11 +49,12 @@ func init() {
JWTSecret: config.JWTSecret, JWTSecret: config.JWTSecret,
CSRFSecret: config.CSRFSecret, CSRFSecret: config.CSRFSecret,
IsProd: config.AppEnv == "production", IsProd: config.AppEnv == "production",
IsRegEnabled: config.AccountCreationEnabled,
Domain: config.Domain, Domain: config.Domain,
FrontendURL: config.FrontendURL, FrontendURL: config.FrontendURL,
} }
log.Debug().Msgf("IsProd=%t, Domain='%s', FrontendURL='%s'", svcConfig.IsProd, svcConfig.Domain, svcConfig.FrontendURL) log.Debug().Msgf("IsProd=%t, IsRegEnabled=%t, Domain='%s', FrontendURL='%s'", svcConfig.IsProd, svcConfig.IsRegEnabled, svcConfig.Domain, svcConfig.FrontendURL)
log.Debug().Msg("Initialization completed") log.Debug().Msg("Initialization completed")
} }

View File

@ -8,6 +8,10 @@
export let bottomText: string export let bottomText: string
export let bottomLink: string export let bottomLink: string
const ACCOUNT_CREATION_ENABLED = (import.meta.env.VITE_ACCOUNT_CREATION_ENABLED || "0") === "1"
console.log(`[VIEW] Account creation enabled: ${ACCOUNT_CREATION_ENABLED}`)
// local state
let username = "" let username = ""
let password = "" let password = ""
let usernameError = "" let usernameError = ""
@ -73,6 +77,11 @@
</div> </div>
{/if} {/if}
{#if !ACCOUNT_CREATION_ENABLED && formName === "Register"}
<div>
<p>Registration disabled.</p>
</div>
{:else}
<form class="space-y-5" on:submit|preventDefault={handleSubmit}> <form class="space-y-5" on:submit|preventDefault={handleSubmit}>
<div class="form-group"> <div class="form-group">
<input <input
@ -102,15 +111,18 @@
{formName} {formName}
</button> </button>
</form> </form>
{/if}
{#if ACCOUNT_CREATION_ENABLED}
<p class="text-center text-sm font-medium"> <p class="text-center text-sm font-medium">
{bottomText} {bottomText}
<a href={bottomLink}> here </a> <a href={bottomLink}> here </a>
</p> </p>
{/if}
</div> </div>
</div> </div>
<!-- TODO: add footer with a randomly picked quote (font-copernicus) --> <!-- TODO: add footer with randomized quotes (see KF impl., font-copernicus) -->
<div class="absolute right-4 top-4"> <div class="absolute right-4 top-4">
<ThemeToggle /> <ThemeToggle />