Conversation
Add an admin-managed registration code system behind a new RegistrationCodeEnabled switch (default off): - New registration_codes table (no quota, unused/used only) with atomic single-use consumption via row lock + status CAS - Admin CRUD at /api/registration_code/* and a Registration Codes page cloned from redemption codes (used rows show avatar + username via a LEFT JOIN, no N+1) - Email/password Register requires and consumes a code inside the same transaction as user creation - Standard OAuth (GitHub/Discord/OIDC/LinuxDO) new users get a pending oauth_register auth flow and must submit a code via POST /api/oauth/complete_registration; existing users log in directly; WeChat/Telegram/Passkey untouched - The gate stacks strictly after RegisterEnabled/PasswordRegisterEnabled and behavior is unchanged when the switch is off - Backend i18n (en/zh-CN/zh-TW) and frontend i18n (7 locales) - Tests: stacking invariants, concurrent single-use, OAuth flow retry and replay protection, switch-off regression
There was a problem hiding this comment.
Pull request overview
Adds a registration-code gate to sign-up flows (email/password and standard OAuth) behind a new RegistrationCodeEnabled switch, plus admin CRUD and UI for managing single-use registration codes.
Changes:
- Introduces
registration_codespersistence + atomic single-use consumption, and exposes admin CRUD endpoints under/api/registration_code/*. - Gates email/password registration and standard OAuth “new user” registration behind a registration code when enabled (with a pending
oauth_registerflow for OAuth). - Adds an admin “Registration Codes” UI (table, create/update/delete, bulk copy) and wires the feature into sidebar navigation and auth/system settings.
Reviewed changes
Copilot reviewed 56 out of 56 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| web/src/routeTree.gen.ts | Adds the authenticated route entry for the registration codes page. |
| web/src/routes/oauth/$provider.tsx | Adds client-side OAuth completion UI for registration-code-required flow. |
| web/src/routes/_authenticated/registration-codes/index.tsx | Adds admin-only route for the Registration Codes page. |
| web/src/i18n/locales/zh.json | Adds some new registration-code-related translations (ZH). |
| web/src/i18n/locales/zh-TW.json | Adds some new registration-code-related translations (ZH-TW). |
| web/src/i18n/locales/vi.json | Adds some new registration-code-related translations (VI). |
| web/src/i18n/locales/ru.json | Adds some new registration-code-related translations (RU). |
| web/src/i18n/locales/ja.json | Adds some new registration-code-related translations (JA). |
| web/src/i18n/locales/fr.json | Adds some new registration-code-related translations (FR). |
| web/src/i18n/locales/en.json | Adds some new registration-code-related translations (EN). |
| web/src/i18n/locales/_reports/_sync-report.json | Updates i18n sync report output (notably zh-TW missingCount). |
| web/src/hooks/use-sidebar-data.ts | Conditionally shows “Registration Codes” in the admin sidebar when enabled. |
| web/src/features/system-settings/types.ts | Adds RegistrationCodeEnabled to auth settings types. |
| web/src/features/system-settings/auth/section-registry.tsx | Wires RegistrationCodeEnabled into settings default values. |
| web/src/features/system-settings/auth/index.tsx | Sets default RegistrationCodeEnabled: false. |
| web/src/features/system-settings/auth/basic-auth-section.tsx | Adds settings toggle UI for registration code requirement. |
| web/src/features/registration-codes/types.ts | Adds TS types/schemas for registration codes feature. |
| web/src/features/registration-codes/lib/utils.ts | Adds client-side expiry helpers for registration codes. |
| web/src/features/registration-codes/lib/registration-code-form.ts | Adds Zod schema + mapping helpers for create/update form payloads. |
| web/src/features/registration-codes/lib/index.ts | Exports registration-code feature utilities. |
| web/src/features/registration-codes/index.tsx | Adds feature entry component/layout for Registration Codes page. |
| web/src/features/registration-codes/constants.ts | Adds status constants + error/success message keys for UI. |
| web/src/features/registration-codes/components/registration-codes-table.tsx | Adds list/search/filter UI with pagination and empty state. |
| web/src/features/registration-codes/components/registration-codes-provider.tsx | Adds context/provider for dialogs and table refresh triggers. |
| web/src/features/registration-codes/components/registration-codes-primary-buttons.tsx | Adds primary actions (create, delete invalid) with confirmation. |
| web/src/features/registration-codes/components/registration-codes-mutate-drawer.tsx | Adds create/update drawer UI (name, expiry, count). |
| web/src/features/registration-codes/components/registration-codes-mobile-list.tsx | Adds mobile list rendering for registration codes. |
| web/src/features/registration-codes/components/registration-codes-dialogs.tsx | Wires mutate drawer + delete dialog. |
| web/src/features/registration-codes/components/registration-codes-delete-dialog.tsx | Adds delete confirmation dialog. |
| web/src/features/registration-codes/components/registration-codes-columns.tsx | Adds table column definitions and filtering logic. |
| web/src/features/registration-codes/components/registration-code-used-cell.tsx | Renders “used by” username/avatar fallback. |
| web/src/features/registration-codes/components/data-table-row-actions.tsx | Adds per-row actions (edit/delete) with disabled rules. |
| web/src/features/registration-codes/components/data-table-bulk-actions.tsx | Adds bulk copy action for selected codes. |
| web/src/features/registration-codes/api.ts | Adds frontend API calls for registration code CRUD/search. |
| web/src/features/auth/types.ts | Adds registration_code fields to payload/status types. |
| web/src/features/auth/sign-up/components/sign-up-form.tsx | Adds registration code input field when required and includes it in payload. |
| web/src/features/auth/constants.ts | Extends signup form schema with optional registrationCode. |
| web/src/features/auth/api.ts | Adds completeOAuthRegistration client API call. |
| router/api-router.go | Adds /api/oauth/complete_registration and admin /api/registration_code/* routes. |
| model/user.go | Adds non-persisted RegistrationCode field for JSON binding. |
| model/registration_code.go | Adds model, queries (JOIN username), and atomic consumption logic. |
| model/registration_code_test.go | Adds model-level tests for filtering/join and single-use consumption. |
| model/option.go | Adds RegistrationCodeEnabled to option map initialization/update. |
| model/main.go | Includes RegistrationCode in migrations. |
| model/auth_flow.go | Adds oauth_register auth flow purpose constant. |
| i18n/locales/zh-TW.yaml | Adds backend i18n messages for registration codes (zh-TW). |
| i18n/locales/zh-CN.yaml | Adds backend i18n messages for registration codes (zh-CN). |
| i18n/locales/en.yaml | Adds backend i18n messages for registration codes (en). |
| i18n/keys.go | Adds backend i18n key constants for registration codes. |
| controller/user.go | Gates email/password registration behind registration codes when enabled. |
| controller/registration_code.go | Adds admin CRUD controllers for registration codes. |
| controller/register_registration_code_test.go | Adds controller-level tests for registration-code-gated register behavior. |
| controller/oauth.go | Adds OAuth pending-registration flow + completion endpoint. |
| controller/oauth_registration_code_test.go | Adds tests for OAuth gated registration flow completion and invariants. |
| controller/misc.go | Exposes registration_code_enabled in status response. |
| common/constants.go | Adds RegistrationCodeEnabled and registration-code status constants. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+142
to
+149
| if code.ExpiredTime != 0 && code.ExpiredTime < common.GetTimestamp() { | ||
| common.ApiErrorI18n(c, i18n.MsgRegistrationCodeExpireTimeInvalid) | ||
| return | ||
| } | ||
| // If you add more fields, please also update RegistrationCode.Update() | ||
| cleanCode.Name = code.Name | ||
| cleanCode.ExpiredTime = code.ExpiredTime | ||
| err = cleanCode.Update() |
Comment on lines
+299
to
+303
| <p className='text-muted-foreground text-sm'> | ||
| {i18next.t( | ||
| 'This site requires a registration code to create a new account. Enter it to finish signing up.' | ||
| )} | ||
| </p> |
Comment on lines
+169
to
+172
| emptyTitle={t('No Registration Codes Found')} | ||
| emptyDescription={t( | ||
| 'No registration codes available. Create your first registration code to get started.' | ||
| )} |
Comment on lines
+95
to
+99
| export const ERROR_MESSAGES = { | ||
| UNEXPECTED: 'An unexpected error occurred', | ||
| LOAD_FAILED: 'Failed to load registration codes', | ||
| SEARCH_FAILED: 'Failed to search registration codes', | ||
| CREATE_FAILED: 'Failed to create registration code', |
- UpdateRegistrationCode now enforces the same 1-20 rune name rule as create, with a regression test - Add the 13 registration-code UI keys that were missing from en.json (error/success toasts, drawer descriptions, empty state, OAuth completion hint) and translate them in all 7 locales
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an admin-managed registration code system behind a new
RegistrationCodeEnabledswitch (default off):registration_codestable (no quota; statuses unused(1)/used(3) only) with atomic single-use consumption (row lock + status CAS). Admin CRUD at/api/registration_code/*plus a "Registration Codes" admin page cloned from redemption codes; used rows show the consuming user's avatar + username via a LEFT JOIN (no N+1).oauth_registerauth flow (10 min TTL) and must submit a code viaPOST /api/oauth/complete_registration; wrong codes leave the flow retryable; existing users log in directly. WeChat/Telegram/Passkey paths untouched.RegisterEnabled/PasswordRegisterEnabled(re-checked at OAuth completion time) and behavior with the switch off is unchanged.Testing
go build ./...passes;go test ./model/ ./controller/passes, including new tests for: stacking invariants, concurrent single-use (exactly one winner), invalid/expired/used code rejection, OAuth flow retry + replay protection,RegisterEnabledre-check at completion, and switch-off regression.tsgotypecheck passes, oxlint clean for new files,i18n:syncreports 0 missing keys for all locales. (rsbuild buildfails on this machine's Node 18 even on a clean tree — pre-existing environment issue, unrelated to this change.)