diff --git a/AGENTS.md b/AGENTS.md index e26ef34..72c9226 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1087,20 +1087,23 @@ sudo docker compose up -d next-app ### The `.dockerignore` situation (known issue) -There are two `.dockerignore` files: +There is one `.dockerignore` file at the repo root: `/.dockerignore`. Docker always +reads the `.dockerignore` from the root of the build context, which is set to `../` +(the repo root) in `compose.yml` — so the root file is the only one that ever applies. -- `/.dockerignore` (root) — has `.env` commented out, meaning the `.env` file IS - included in the Docker build context -- `/docker/.dockerignore` — explicitly excludes `.env` +The `.env` file is intentionally included in the build context (the `.env` lines are +commented out in `/.dockerignore`). This is how `SENTRY_AUTH_TOKEN` and `NEXT_PUBLIC_*` +variables reach the Next.js build step inside the container. -The Docker build context is set to the repo root in `compose.yml`. The root -`.dockerignore` is the one that applies. Because `.env` is not excluded, it gets sent -to the builder and environment variables are available at build time. This is how -`SENTRY_AUTH_TOKEN` and other build-time vars reach the Next.js build step. +Do not un-comment those lines without understanding the full implications — removing +`.env` from the build context would break Sentry source map uploads and +`NEXT_PUBLIC_*` variable baking into the client bundle. -This is a known imperfect approach but it works. Do not "fix" it without understanding -the full implications — removing `.env` from the build context would break Sentry -source map uploads and `NEXT_PUBLIC_*` variable baking into the client bundle. +**Note on `docker/.env`:** This file is entirely separate and serves a different +purpose. It is read by Docker Compose itself (not the build) to interpolate the +`${VARIABLE}` placeholders in `compose.yml` — things like container names, network +names, and Convex origin URLs. It is not the same as the root `/.env` and the two +are not interchangeable. ### Convex data persistence @@ -1287,43 +1290,16 @@ native fix for this or if a custom update script is needed. --- -**2. Password validation mismatch** ⚠️ Medium priority +**2. Password validation mismatch** ✅ Fixed -`packages/backend/types/auth.ts` exports `PASSWORD_REGEX` which requires special -characters. `packages/backend/convex/custom/auth/providers/password.ts::validatePassword()` -does NOT check for special characters. These two are inconsistent. The frontend sign-in -form does enforce special characters via its own Zod schema, but the backend validation -is weaker than the type definition implies. Either align `validatePassword()` to match -`PASSWORD_REGEX`, or update `PASSWORD_REGEX` to not require special characters. +`validatePassword()` in `packages/backend/convex/custom/auth/providers/password.ts` +now fully matches `PASSWORD_REGEX` in `packages/backend/types/auth.ts`. Both enforce: +minimum 8 characters, maximum 100, no whitespace, at least one digit, one lowercase +letter, one uppercase letter, and at least one special character (`[\p{P}\p{S}]`). --- -**3. `import type` enforcement removed** ✅ Fixed - -The `@typescript-eslint/consistent-type-imports` and `import/consistent-type-specifier-style` -rules that forced separate `import type` statements have been removed from -`tools/eslint/base.ts`. Type imports can now be mixed inline or on separate lines — -whatever reads most naturally in context. - ---- - -**4. `const` arrow function lint rule added** ✅ Fixed - -`eslint-plugin-prefer-arrow-functions` has been added to `tools/eslint/base.ts` and the -`prefer-arrow-functions/prefer-arrow-functions` rule is now enforced as a warning. All -function declarations across the codebase have been auto-converted to `const` arrow -function syntax. - ---- - -**5. Turbo generator uses pnpm** ✅ Fixed in this session - -`turbo/generators/config.ts` previously called `pnpm i` and `pnpm prettier`. This has -been fixed to use `bun install` and `bun prettier`. - ---- - -**6. Root `.dockerignore` includes `.env` in build context** ℹ️ Known, works intentionally +**3. Root `.dockerignore` includes `.env` in build context** ℹ️ Known, works intentionally The root `.dockerignore` has `.env` commented out, meaning the `.env` file is sent to the Docker build context. This is how build-time env vars (Sentry token, `NEXT_PUBLIC_*`) @@ -1331,9 +1307,12 @@ reach the Next.js build step. It's a known imperfect approach but fully function A proper solution would use Docker build args (`ARG`) or multi-stage secrets, but this requires careful restructuring to avoid breaking Sentry source map uploads. +The redundant `docker/.dockerignore` has been deleted — it was never read by Docker +since the build context is always the repo root. + --- -**7. In-memory IP banning resets on restart** ℹ️ Future enhancement +**4. In-memory IP banning resets on restart** ℹ️ Future enhancement `src/lib/proxy/ban-sus-ips.ts` stores bans in a JavaScript `Map`. Bans reset whenever the Next.js server restarts (container restart, redeploy, etc.). A more robust solution @@ -1342,7 +1321,7 @@ job) or to Redis. --- -**8. `apps/next/src/lib/metadata.ts` has hardcoded branding** ⚠️ Template concern +**5. `apps/next/src/lib/metadata.ts` has hardcoded branding** ⚠️ Template concern When using this as a template for a new project, `metadata.ts` must be updated: the title template (`'%s | Convex Monorepo'`) and any other project-specific strings. @@ -1350,7 +1329,7 @@ Same for `next.config.js` `images.remotePatterns` (currently `*.gbrown.org`). --- -**9. No CI/CD** ℹ️ Future enhancement +**6. No CI/CD** ℹ️ Future enhancement There is no `.github/workflows/` directory. All deployment is done manually via SSH. A future enhancement would add GitHub Actions (or Gitea Actions, since this repo is @@ -1358,7 +1337,7 @@ on Gitea) for automated lint and typecheck on pull requests. --- -**10. Scripts organization** ℹ️ Future exploration +**7. Scripts organization** ℹ️ Future exploration Currently: @@ -1372,14 +1351,14 @@ moving everything to `docker/scripts/`. --- -**11. Expo `eas.json` specifies pnpm** ⚠️ Low priority (Expo is WIP anyway) +**8. Expo `eas.json` specifies pnpm** ⚠️ Low priority (Expo is WIP anyway) `apps/expo/eas.json` specifies `pnpm 9.15.4` as the package manager. Should specify bun. This is low priority since the Expo app is not in active development. --- -**12. React Email templates not yet implemented** ℹ️ Future enhancement +**9. React Email templates not yet implemented** ℹ️ Future enhancement `@react-email/components` and `react-email` are in `packages/backend/package.json` as planned dependencies. The current `usesend.ts` uses inline HTML strings for email diff --git a/docker/.dockerignore b/docker/.dockerignore deleted file mode 100644 index 680bb19..0000000 --- a/docker/.dockerignore +++ /dev/null @@ -1,49 +0,0 @@ -# Dependencies - MUST exclude these -node_modules -**/node_modules -.pnp -.pnp.js - -# Turbo -.turbo -**/.turbo - -# Next.js build artifacts -.next -**/.next -out -**/out - -# Development -.git -.gitignore -*.log -.env -.env.* -!.env.example -.vscode -.idea - -# Tests -**/__tests__ -**/*.test.ts -**/*.test.tsx -**/*.spec.ts - -# Build artifacts -dist -**/dist -build -**/build - -# Convex local -packages/backend/.convex - -# OS -.DS_Store -Thumbs.db - -# Docker -docker -Dockerfile -.dockerignore diff --git a/docker/compose.yml b/docker/compose.yml index a4f8814..5f5571b 100644 --- a/docker/compose.yml +++ b/docker/compose.yml @@ -11,14 +11,6 @@ services: container_name: ${NEXT_CONTAINER_NAME} environment: - NODE_ENV - - SENTRY_AUTH_TOKEN - - NEXT_PUBLIC_SITE_URL - - NEXT_PUBLIC_CONVEX_URL - - NEXT_PUBLIC_PLAUSIBLE_URL - - NEXT_PUBLIC_SENTRY_DSN - - NEXT_PUBLIC_SENTRY_URL - - NEXT_PUBLIC_SENTRY_ORG - - NEXT_PUBLIC_SENTRY_PROJECT_NAME hostname: ${NEXT_CONTAINER_NAME} domainname: ${NEXT_DOMAIN_NAME} networks: ['${NETWORK:-nginx-bridge}'] diff --git a/packages/backend/convex/custom/auth/providers/password.ts b/packages/backend/convex/custom/auth/providers/password.ts index 7ef8ed2..bc2a311 100644 --- a/packages/backend/convex/custom/auth/providers/password.ts +++ b/packages/backend/convex/custom/auth/providers/password.ts @@ -24,9 +24,11 @@ export const validatePassword = (password: string): boolean => { if ( password.length < 8 || password.length > 100 || + /\s/.test(password) || !/\d/.test(password) || !/[a-z]/.test(password) || - !/[A-Z]/.test(password) + !/[A-Z]/.test(password) || + !/[\p{P}\p{S}]/u.test(password) ) { return false; }