Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
9a0e482
ci: prove the Windows behaviour on a Windows runner
codeGlaze Sep 18, 2026
5829e85
ci: source check_port_available from start.sh, where it actually lives
codeGlaze Sep 18, 2026
6636369
scripts: handle both kinds of Windows pid, and stop crying wolf
codeGlaze Sep 18, 2026
71c4d26
ci: assert the quiet case on a port no other step has touched
codeGlaze Sep 18, 2026
5d2bbd1
Fix locale-dependent failures in ETag and CSP config
codeGlaze Sep 19, 2026
c27cbd3
scripts: make the Windows paths work instead of silently lying
codeGlaze Sep 18, 2026
798b126
ci: run the Windows job on the branch that now carries the work
codeGlaze Sep 20, 2026
4e972cf
Correct the CSP docs, and say which policy the server starts under
codeGlaze Sep 20, 2026
cf8a6d7
Surface the effective config when the launcher starts
codeGlaze Sep 20, 2026
bcf8526
Put config where it is read, and repair --check, which died silently
codeGlaze Sep 20, 2026
402ea5e
Add tests that pin both defects, and prove they fail without the fix
codeGlaze Sep 20, 2026
b86d3d1
Pin the locale on name-to-kw and the two name filters
codeGlaze Sep 20, 2026
55adc9e
Address the review on #695: six findings, each reproduced first
codeGlaze Sep 20, 2026
89f8d17
Stop the env template from dictating the Datomic URL to both runtimes
codeGlaze Sep 20, 2026
dcd0483
Address the second review on #695: eight findings, each reproduced first
codeGlaze Sep 20, 2026
b6df809
Make the dev service map honour PORT, so the scripts and the server a…
codeGlaze Sep 20, 2026
c9fd5a5
Finish the CSP docs fix: three user-facing docs still described Repor…
codeGlaze Sep 20, 2026
7703e36
Mirror the server exactly in dev_mode_blocks_figwheel, including empt…
codeGlaze Sep 21, 2026
c0a6fa7
Drop the commented-out datomic-pro coordinate and the comment that ou…
codeGlaze Sep 21, 2026
813fdbb
Mirror the server's three-way CSP cond, and stop the warning claiming…
codeGlaze Sep 21, 2026
db2f7ee
Add orcpub.env, convert every env read to it, and make the old patter…
codeGlaze Sep 21, 2026
f412602
Keep postal's inputs as empty strings: orcpub.env regressed the Docke…
codeGlaze Sep 21, 2026
e4a6964
Roll back the account when the verification email fails
codeGlaze Sep 21, 2026
67cb98e
Correct the severity claim: the stuck account is recoverable via resend
codeGlaze Sep 21, 2026
50e4c4c
Finish the severity correction: two copies were still wrong
codeGlaze Sep 21, 2026
5d7b4b2
Verify on creation when no SMTP is configured, making the .env promis…
codeGlaze Sep 22, 2026
fcaf894
Fail closed when email config goes missing: auto-verify now needs an …
codeGlaze Sep 23, 2026
896d186
Say at startup what registration will actually do
codeGlaze Sep 23, 2026
8b33c26
Set EMAIL_FROM_ADDRESS explicitly in the template
codeGlaze Sep 24, 2026
4909ea1
Document ALLOW_UNVERIFIED_REGISTRATION, and make the KB references re…
codeGlaze Sep 24, 2026
9ca0560
Write the new settings for humans, and point the code at the doc that…
codeGlaze Sep 24, 2026
969cf64
Read the JWT secret through config/signature so Docker secrets work
codeGlaze Sep 24, 2026
7b16f2e
Guard the two secret-backed settings against being read from the env …
codeGlaze Sep 24, 2026
b29d89e
Fix the three registration paths Greptile flagged, and pin lein in th…
codeGlaze Sep 25, 2026
94a71ea
Only restore the previous verification key if it is still ours
codeGlaze Sep 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions .clj-kondo/config.edn
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,25 @@
:exclude-files "resources/public/js/compiled"
:output {:exclude-files [".*resources/public/js/compiled.*"
".*docker/scripts/.*"]}
:linters {;; Enabled at :warning so NEW accidental shadows are caught.
:linters {;; A BLANK ENVIRONMENT VALUE IS AN ABSENT ONE, and (or (env :k) default)
;; does not implement that: environ returns "" for an exported-but-empty
;; variable and "" is truthy, so the default never applies. That shape
;; was written independently at five sites and cost, among others, JWTs
;; signed and verified against the empty string.
;;
;; orcpub.config already had a correct accessor and routes.clj read
;; (environ/env :signature) raw anyway, four times -- which is why this
;; is a lint rule and not just a helper. Read through orcpub.env/value.
;; :error, not :warning -- `lein lint` runs with --fail-level error, so
;; this is the difference between a rule and a suggestion. The helper
;; it points at already existed once and was bypassed.
:discouraged-var
{:level :error
environ.core/env
{:message "Use orcpub.env/value -- (or (env :k) d) treats an empty value as set. See orcpub.env."}
java.lang.System/getenv
{:message "Use orcpub.env/value -- environ already reads env vars, and this skips the blank check."}}
;; Enabled at :warning so NEW accidental shadows are caught.
;; :exclude covers established patterns: core vars used as param names
;; (name, key, type, etc.) and domain terms used as both defs and params
;; (level, ability, armor, etc.) across modifier/option/character code.
Expand Down Expand Up @@ -107,10 +125,21 @@
(orcpub.routes-test/with-conn)
(orcpub.routes.folder-test/with-conn)
(orcpub.email-change-test/with-conn)
(orcpub.registration-rollback-test/with-conn)
(user/with-db)]}}
;; native/cljs and web/cljs are separate source roots; kondo doesn't know
;; about them so ns names appear to mismatch their file paths.
:config-in-ns {orcpub.core {:linters {:namespace-name-mismatch {:level :off}}}
;; orcpub.env is the one place allowed to read the environment; the whole
;; point of the namespace is to be the single exception.
:config-in-ns {orcpub.env {:linters {:discouraged-var {:level :off}}}
;; These two STUB environ.core/env with with-redefs, which is how
;; you test the accessor and the locale behaviour at all -- kondo
;; counts the var reference as a use. Exempted by namespace rather
;; than for all of test/, so an ordinary bare read in a test is
;; still an error (routes_test.clj had one).
orcpub.env-test {:linters {:discouraged-var {:level :off}}}
orcpub.config-test {:linters {:discouraged-var {:level :off}}}
orcpub.core {:linters {:namespace-name-mismatch {:level :off}}}
orcpub.views {:linters {:namespace-name-mismatch {:level :off}}}
orcpub.dnd.e5.native-views {:linters {:namespace-name-mismatch {:level :off}}}}
;; with-conn macros use bare symbol bindings — handled via
Expand Down
43 changes: 38 additions & 5 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,22 @@ TZ=America/Chicago
# Old URLs with ?password= still work — the embedded password takes priority.
ADMIN_PASSWORD=change-me-admin
DATOMIC_PASSWORD=change-me-datomic
DATOMIC_URL=datomic:dev://datomic:4334/orcpub
# Left COMMENTED OUT on purpose, so that each way of running picks its own
# correct value instead of inheriting the other's:
#
# bare metal -> config.clj/default-datomic-uri = datomic:dev://localhost:4334/orcpub
# docker -> docker-compose.yaml already defaults it to the "datomic"
# service hostname, which only resolves inside that network
#
# Setting it here would defeat both. Compose reads this .env for substitution,
# so an uncommented localhost would override compose's own default and break
# the container; an uncommented "datomic" hostname breaks every non-Docker
# install, which is how it used to ship.
#
# Uncomment ONLY for a database somewhere else -- a remote transactor, a
# non-default port, or Datomic SQL storage:
# DATOMIC_URL=datomic:dev://localhost:4334/orcpub
# DATOMIC_URL=datomic:sql://orcpub?jdbc:postgresql://db:5432/datomic

# --- Transactor Tuning ---
# These rarely need changing. See docker/transactor.properties.template.
Expand All @@ -48,8 +63,11 @@ SIGNATURE=change-me-to-something-unique-and-long
# Content Security Policy (strict|permissive|none)
CSP_POLICY=strict

# Dev mode: CSP violations are logged (Report-Only) instead of blocked,
# allowing Figwheel hot-reload scripts to execute.
# Dev mode: no CSP header is sent at all, so Figwheel's scripts and its
# websocket (ws://localhost:3449) work. Leave this true for development.
# With DEV_MODE unset or false, CSP_POLICY=strict sends an ENFORCING policy
# whose connect-src does not include the Figwheel socket, and hot reload is
# blocked with no obvious cause.
# Must be the string "true" (case-insensitive). Any other value is treated as false.
DEV_MODE=true

Expand All @@ -72,16 +90,31 @@ LOG_DIR=
# FIGWHEEL_CONNECT_URL=

# --- Email (SMTP) ---
# Leave EMAIL_SERVER_URL empty to disable email functionality
# EMAIL_SERVER_URL empty means this deployment cannot send mail, and registration
# then REFUSES to create accounts -- deliberately, because a dropped or typo'd
# value would otherwise silently turn a public site into open registration.
#
# To actually run without email, say so: ALLOW_UNVERIFIED_REGISTRATION=true.
# Accounts are then verified on creation and no mail is ever sent. Only sensible
# for a private instance where you hand out the accounts, since nobody proves
# they own the address they typed.
EMAIL_SERVER_URL=
EMAIL_ACCESS_KEY=
EMAIL_SECRET_KEY=
EMAIL_SERVER_PORT=587
EMAIL_FROM_ADDRESS=
# MUST be an address your SMTP provider is authorised to send as (SPF/DKIM),
# not just any address you own. Left blank it falls back to
# branding/email-from-address (no-reply@orcpub.com), which your provider
# almost certainly will not accept -- set it.
EMAIL_FROM_ADDRESS=no-reply@example.com
EMAIL_ERRORS_TO=
EMAIL_SSL=FALSE
EMAIL_TLS=FALSE

# Accept registrations without verifying the address. Requires EMAIL_SERVER_URL
# to be empty; ignored otherwise. Private instances only.
ALLOW_UNVERIFIED_REGISTRATION=false

# --- Branding (optional) ---
# Override app identity for forks. All have sensible defaults in fork/branding.clj.
# APP_NAME=Dungeon Master's Vault
Expand Down
61 changes: 61 additions & 0 deletions .github/workflows/locale.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Runs the JVM suite under non-English locales.
#
# Everything the locale-safety work fixed was invisible to an English-locale CI:
# an unlocalised date formatter that blanked every webjar asset, CSP_POLICY
# folding to "strıct", name-to-kw producing :ıllusory-script, and two name
# searches returning nothing for an uppercase query. None of them fail under
# en_US, so en_US alone can never catch the next one.
#
# tr_TR is the high-value entry: Turkish and Azerbaijani are the only locales
# whose ASCII case folding differs, so they catch that whole class. es_ES
# catches date parsing, which tr_TR also catches -- one non-English entry would
# do, but es_ES is where the original bug report came from, so it stays as a
# named regression guard.

name: Locale

on:
push:
branches: [hotfix/locale-safety, develop, main]
pull_request:
branches: [develop, main]
Comment thread
codeGlaze marked this conversation as resolved.
workflow_dispatch:

permissions:
contents: read

jobs:
jvm-suite:
name: JVM suite under ${{ matrix.locale }}
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
include:
- locale: tr_TR
java_opts: -Duser.language=tr -Duser.country=TR
- locale: es_ES
java_opts: -Duser.language=es -Duser.country=ES
steps:
- uses: actions/checkout@v4

- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '21'

# Pinned to the version continuous-integration.yml uses. `stable` is a
# moving ref, so an upstream release could change or break this check.
- name: Install Leiningen
run: |
curl -fsSL -o "$HOME/lein" \
https://raw.githubusercontent.com/technomancy/leiningen/2.11.2/bin/lein
chmod +x "$HOME/lein"
echo "$HOME" >> "$GITHUB_PATH"
"$HOME/lein" version
Comment thread
codeGlaze marked this conversation as resolved.

- name: lein test
env:
JAVA_TOOL_OPTIONS: ${{ matrix.java_opts }}
run: lein test
Loading
Loading