diff --git a/.ai-structure.md b/.ai-structure.md new file mode 100644 index 0000000000..7a40e46fa0 --- /dev/null +++ b/.ai-structure.md @@ -0,0 +1,358 @@ +. +./types.d.ts +./docker +./docker/manifest.rootless.tmpl +./docker/root +./docker/manifest.tmpl +./docker/README.md +./docker/rootless +./BSDmakefile +./tests +./tests/integration +./tests/gitea-lfs-meta +./tests/mysql.ini.tmpl +./tests/e2e +./tests/testdata +./tests/fuzz +./tests/test_utils.go +./tests/sqlite.ini.tmpl +./tests/gitea-repositories-meta +./tests/pgsql.ini.tmpl +./tests/mssql.ini.tmpl +./eslint.json.config.ts +./LICENSE +./models +./models/repo.go +./models/avatars +./models/system +./models/auth +./models/migrations +./models/pull +./models/main_test.go +./models/fixtures +./models/asymkey +./models/packages +./models/unittest +./models/admin +./models/repo +./models/activities +./models/unit +./models/db +./models/dbfs +./models/shared +./models/webhook +./models/secret +./models/perm +./models/user +./models/renderhelper +./models/actions +./models/git +./models/organization +./models/issues +./models/repo_test.go +./models/project +./eslint.config.ts +./flake.lock +./tools +./tools/generate-svg-vscode-extensions.json +./tools/test-e2e.sh +./tools/code-batch-process.go +./tools/gocovmerge.go +./tools/lint-templates-svg.ts +./tools/generate-images.ts +./tools/codeformat +./tools/generate-svg.ts +./tools/test-echo.go +./tools/watch.sh +./vitest.config.ts +./CHANGELOG.md +./+x +./CODE_OF_CONDUCT.md +./CLAUDE.md +./README.zh-tw.md +./web_src +./web_src/svg +./web_src/fomantic +./web_src/js +./web_src/css +./CHANGELOG-archived.md +./custom +./custom/conf +./contrib +./contrib/systemd +./contrib/init +./contrib/update_dependencies.sh +./contrib/fhs-compliant-script +./contrib/launchd +./contrib/backport +./contrib/README +./contrib/legal +./contrib/supervisor +./contrib/options +./contrib/upgrade.sh +./contrib/ide +./contrib/gitea-monitoring-mixin +./templates +./templates/package +./templates/post-install.tmpl +./templates/status +./templates/devtest +./templates/projects +./templates/base +./templates/org +./templates/swagger +./templates/custom +./templates/admin +./templates/repo +./templates/shared +./templates/webhook +./templates/api +./templates/home.tmpl +./templates/install.tmpl +./templates/user +./templates/explore +./templates/mail +./update-gitea.sh +./flake.nix +./DCO +./MAINTAINERS +./routers +./routers/common +./routers/install +./routers/web +./routers/private +./routers/init.go +./routers/api +./routers/utils +./pnpm +./package.json +./snap +./snap/snapcraft.yaml +./services +./services/uinotification +./services/convert +./services/secrets +./services/wiki +./services/auth +./services/migrations +./services/pull +./services/projects +./services/repository +./services/markup +./services/oauth2_provider +./services/asymkey +./services/org +./services/task +./services/packages +./services/mailer +./services/forms +./services/issue +./services/webtheme +./services/attachment +./services/mirror +./services/versioned_migration +./services/agit +./services/context +./services/release +./services/doctor +./services/gitdiff +./services/webhook +./services/automerge +./services/contexttest +./services/cron +./services/user +./services/automergequeue +./services/feed +./services/actions +./services/git +./services/lfs +./services/notify +./services/indexer +./services/externalaccount +./go.mod +./assets +./assets/misspellings.csv +./assets/logo.svg +./assets/emoji.json +./assets/go-licenses.json +./assets/favicon.svg +./smart-build.sh +./Dockerfile.rootless +./build +./build/generate-go-licenses.go +./build/update-locales.sh +./build/generate-emoji.go +./build/generate-bindata.go +./build/generate-gitignores.go +./build/test-env-check.sh +./build/test-env-prepare.sh +./pyproject.toml +./updates.config.ts +./tsconfig.json +./pnpm-lock.yaml +./crowdin.yml +./SECURITY.md +./options +./options/locale +./options/gitignore +./options/fileicon +./options/label +./options/license +./options/readme +./docs +./docs/guideline-frontend.md +./docs/release-management.md +./docs/guideline-backend.md +./docs/community-governance.md +./playwright.config.ts +./cmd +./cmd/manager_logging.go +./cmd/admin_auth_ldap_test.go +./cmd/web_acme.go +./cmd/admin_user_delete.go +./cmd/admin_user_must_change_password_test.go +./cmd/admin_user_create.go +./cmd/admin_regenerate.go +./cmd/generate.go +./cmd/admin_auth.go +./cmd/dump.go +./cmd/admin_user_must_change_password.go +./cmd/doctor_test.go +./cmd/migrate.go +./cmd/admin_auth_oauth.go +./cmd/main_test.go +./cmd/actions.go +./cmd/cmd_test.go +./cmd/cert_test.go +./cmd/migrate_storage_test.go +./cmd/web_graceful.go +./cmd/doctor.go +./cmd/admin_user_delete_test.go +./cmd/embedded.go +./cmd/manager.go +./cmd/config.go +./cmd/admin_user_change_password.go +./cmd/cert.go +./cmd/hook_test.go +./cmd/web.go +./cmd/hook.go +./cmd/admin_auth_ldap.go +./cmd/admin_user_list.go +./cmd/admin_user_change_password_test.go +./cmd/admin_auth_smtp_test.go +./cmd/web_https.go +./cmd/docs.go +./cmd/admin_user_create_test.go +./cmd/migrate_storage.go +./cmd/admin_auth_oauth_test.go +./cmd/serv.go +./cmd/admin_user_generate_access_token.go +./cmd/admin.go +./cmd/config_test.go +./cmd/doctor_convert.go +./cmd/main.go +./cmd/dump_repo.go +./cmd/keys.go +./cmd/admin_user.go +./cmd/admin_auth_smtp.go +./cmd/restore_repo.go +./cmd/mailer.go +./cmd/cmd.go +./AGENTS.md +./README.zh-cn.md +./Dockerfile +./tailwind.config.ts +./Makefile +./README.md +./main.go +./go.sum +./uv.lock +./stylelint.config.js +./CONTRIBUTING.md +./modules +./modules/reqctx +./modules/public +./modules/references +./modules/httplib +./modules/hcaptcha +./modules/generate +./modules/tailmsg +./modules/turnstile +./modules/system +./modules/badge +./modules/eventsource +./modules/htmlutil +./modules/setting +./modules/fileicon +./modules/auth +./modules/migration +./modules/svg +./modules/repository +./modules/markup +./modules/typesniffer +./modules/test +./modules/web +./modules/pprof +./modules/validation +./modules/base +./modules/tempdir +./modules/zstd +./modules/gitrepo +./modules/packages +./modules/testlogger +./modules/process +./modules/templates +./modules/label +./modules/issue +./modules/dump +./modules/metrics +./modules/assetfs +./modules/nosql +./modules/avatar +./modules/updatechecker +./modules/private +./modules/cache +./modules/regexplru +./modules/gtprof +./modules/log +./modules/commitstatus +./modules/session +./modules/highlight +./modules/csv +./modules/proxy +./modules/queue +./modules/uri +./modules/httpcache +./modules/lfstransfer +./modules/options +./modules/webhook +./modules/secret +./modules/json +./modules/globallock +./modules/emoji +./modules/charset +./modules/recaptcha +./modules/user +./modules/paginator +./modules/proxyprotocol +./modules/actions +./modules/optional +./modules/structs +./modules/ssh +./modules/timeutil +./modules/glob +./modules/git +./modules/lfs +./modules/mcaptcha +./modules/util +./modules/sitemap +./modules/graceful +./modules/storage +./modules/cachegroup +./modules/hostmatcher +./modules/container +./modules/translation +./modules/indexer +./modules/analyze +./vite.config.ts +./main_timezones.go diff --git a/.codex-context.md b/.codex-context.md index 3833e7c509..4bee00ee37 100644 --- a/.codex-context.md +++ b/.codex-context.md @@ -1,6 +1,62 @@ -# Generăm o listă cu structura relevantă (fără folderele inutile) -find . -maxdepth 2 -not -path '*/.*' \ - -not -path './node_modules*' \ - -not -path './public*' \ - -not -path './dist*' \ - -not -path './data*' > .ai-structure.txt +# Gitea Codex Context + +Acest fisier este memoria persistenta Codex pentru acest proiect. +Istoric complet al modificarilor: vezi `./.codex-history`. +Baza structurala folosita pentru acest context: `./.ai-structure.md`. + +## Arhitectura generala + +- Entry point-ul principal este `main.go`, care seteaza versiunea aplicatiei in `setting.AppVer` si porneste comenzile din `cmd/`. +- Pornirea serverului web trece prin `cmd/web.go`, iar initializarea globala a aplicatiei instalate se face in `routers/init.go` prin `InitWebInstalled()` si expunerea rutelor prin `NormalRoutes()`. +- Rutele web sunt centralizate in `routers/web/web.go`, in special in `Routes()` si `registerWebRoutes(...)`. +- Rutele API sunt montate din `routers/init.go`: `/api/v1` pentru API public, `/api/internal` pentru rute private, plus zone separate pentru Packages si Actions atunci cand sunt activate. +- Organizarea pe domenii pentru routing este clara: `routers/web/repo/`, `routers/web/org/`, `routers/web/user/`, `routers/web/admin/`, `routers/web/auth/`, respectiv `routers/api/v1/` si celelalte subtree-uri API. +- Modelele de date sunt in `models/`, grupate pe domenii. Zone importante: `models/user/`, `models/repo/`, `models/issues/`, `models/auth/`, `models/organization/`, `models/packages/`, `models/project/`, `models/webhook/`, `models/actions/`. +- Persistenta si infrastructura de baza pentru DB sunt in `models/db/`, iar migrarile in `models/migrations/`. +- Serviciile de business logic sunt in `services/`, cu exemple relevante in `services/auth/`, `services/user/`, `services/repository/`, `services/pull/`, `services/mailer/`, `services/indexer/`, `services/webhook/`, `services/packages/`, `services/actions/`. +- `services/context/` leaga request-ul HTTP de sesiune, user, template data si middleware-ul specific Gitea. +- UI-ul server-side este randat din `templates/`, iar frontend-ul modern si codul browser-side sunt in `web_src/`. + +## Fluxul de autentificare + +- Rutele de autentificare sunt definite in principal in `routers/web/web.go`, sub grupurile `/user`, `/login/oauth` si subgrupurile aferente pentru 2FA, WebAuthn, OpenID si OAuth2. +- Fisierele principale din `routers/web/auth/` sunt: +- `routers/web/auth/auth.go`: login clasic, signup, auto-login din remember cookie, redirect dupa autentificare si orchestration-ul de baza pentru paginile de auth. +- `routers/web/auth/password.go`: forgot password, reset password si forced password change. +- `routers/web/auth/2fa.go`: TOTP si scratch codes pentru pasul secundar de autentificare. +- `routers/web/auth/webauthn.go`: autentificare WebAuthn si passkeys. +- `routers/web/auth/oauth.go`: start si callback pentru provideri OAuth2/OpenID Connect, link-account si auto-registration. +- `routers/web/auth/oauth_signin_sync.go`: sincronizarea datelor utilizatorului dupa autentificare OAuth2. +- `routers/web/auth/oauth2_provider.go`: endpoint-urile providerului OAuth2/OIDC pe care le expune Gitea. +- `routers/web/auth/openid.go`: fluxul OpenID pentru sign-in, connect si register. +- `routers/web/auth/linkaccount.go`: asocierea unui cont extern cu un cont local. +- Template-urile UI pentru auth sunt in `templates/user/auth/`. +- Modelele si serviciile care sustin acest flux sunt in principal in `models/auth/`, `services/auth/`, `services/oauth2_provider/` si `services/externalaccount/`. + +## Tehnologii cheie + +- Backend principal: Go, confirmat prin `go.mod` si majoritatea fisierelor din `cmd/`, `routers/`, `models/`, `services/` si `modules/`. +- Templating server-side: Go templates `.tmpl`, confirmate in `templates/`. +- Frontend principal: TypeScript, confirmat in `web_src/js/` si in fisierele de configurare precum `vite.config.ts`, `vitest.config.ts`, `tailwind.config.ts` si `eslint.config.ts`. +- Componente Vue exista in repo, confirmate de fisiere `.vue` si de `@vitejs/plugin-vue` din `package.json`. +- Stilizare: CSS in `web_src/css/`, plus Tailwind CSS si Fomantic UI. +- Testare si lint frontend: Vitest, Playwright, ESLint si Stylelint. +- Tooling suplimentar confirmat in structura repo: shell scripts, YAML, Dockerfile si Nix. +- Dependintele si resursele statice nu au fost analizate ca obiectiv functional, conform cerintei. + +## Puncte de extensie + +- Pentru o ruta web noua: adauga handler-ul in subtree-ul potrivit din `routers/web/`, apoi inregistreaza ruta in `routers/web/web.go` in `registerWebRoutes(...)`. +- Pentru o ruta API noua: extinde zona relevanta din `routers/api/v1/` sau din alt subtree API deja folosit si monteaza ruta prin entrypoint-urile din `routers/init.go`. +- Pentru logica noua de business: adauga orchestration in `services/` si accesul la date in `models/`, pastrand handler-ele din `routers/` relativ subtiri. +- Pentru un tab nou in meniul principal global: editeaza `templates/base/head_navbar.tmpl`. +- Pentru linkuri globale suplimentare fara a modifica toata structura standard, exista hook-ul template `custom/extra_links` in `templates/base/head_navbar.tmpl`. +- Pentru un tab nou in meniul unui repository: editeaza `templates/repo/header.tmpl`. +- Pentru taburi custom de repo fara rescrierea structurii standard, exista hook-ul `custom/extra_tabs` in `templates/repo/header.tmpl`. +- Pentru submenu-uri din zona repo activity sau sumar repo: verifica `templates/repo/navbar.tmpl` si `templates/repo/sub_menu.tmpl`. +- Pentru zonele de setari user, org sau admin, punctele uzuale sunt template-urile din `templates/user/settings/`, `templates/org/settings/`, `templates/admin/` si rutele aferente din `routers/web/user/`, `routers/web/org/`, `routers/web/admin/`. + +## Observatii utile + +- Versiunea implicita a aplicatiei in build-ul din sursa curenta este `development`, definita in `main.go` si copiata in `setting.AppVer`. +- Structura proiectului separa clar entrypoint-urile, routing-ul, modelele, serviciile si template-urile, ceea ce face extinderile viitoare predictibile. diff --git a/.codex-history b/.codex-history new file mode 100644 index 0000000000..d711a1a712 --- /dev/null +++ b/.codex-history @@ -0,0 +1,30 @@ +ID Modification[date-time] - Version - Type: Modified/Added/Fixed - Summary: + +CTX-2026-04-15T23:22:52Z - development - Type: Added/Modified - Created the persistent Codex project memory for this Gitea workspace. +- 1 - I added `.codex-history` as the permanent English change log requested for this project. +- 2 - I added `.codex-context.md` as the permanent repository context file based on the provided `.ai-structure.md` and the routing/model/service structure already identified earlier. +- 3 - I added a concise architecture map that points to the main entrypoints, route registration layers, data model directories, migration folders, template locations, and service-layer modules. +- 4 - I added a focused authentication overview that identifies the primary files in `routers/web/auth/` and explains the role of each major auth flow component. +- 5 - I added a confirmed technology summary covering Go, Go templates, TypeScript, Vue, Vite, Tailwind CSS, Fomantic UI, Vitest, Playwright, ESLint, and Stylelint. +- 6 - I added practical extension guidance for introducing a new menu tab, a new repository tab, a new web route, or a new API route. +- 7 - I modified `.codex-context.md` to replace the previous placeholder shell snippet with repository-specific documentation that can serve as long-term project memory. +- 8 - I added an explicit reference from `.codex-context.md` to `.codex-history` so the project context always points to the ongoing modification log. +- 9 - I corrected the recorded application version to `development`, matching the current source build value set from `main.go` into `setting.AppVer`. + +CTX-2026-04-15T23:46:18Z - development - Type: Modified - Added explicit repository visibility badges to match the requested GitHub-style presentation more closely. +- 1 - I modified `templates/repo/header.tmpl` so the repository page header now always shows a visibility badge on the right side: `Private`, `Internal`, or `Public`. +- 2 - I modified `templates/shared/repo/list.tmpl` so each repository entry in shared repository lists also shows an explicit visibility badge for `Private`, `Internal`, or `Public`. +- 3 - I added the `Public` label for repositories that previously had no explicit visibility badge, while preserving the existing archived, template, and sha256 labels. +- 4 - I reused existing translation keys and existing badge styling so the change stays visually consistent with the current Gitea UI. + +CTX-2026-04-16T00:31:29Z - development - Type: Modified - Refined repository visibility badges with semantic colors, owner-aware navigation, and broader coverage in repository settings views. +- 1 - I modified `templates/shared/repo/list.tmpl` so `Public` now uses a basic green badge and `Private` now uses a basic red badge, while `Internal` remains neutral. +- 2 - I modified `templates/repo/header.tmpl` so the repository header uses the same color-coded visibility badges and keeps the mobile icon behavior unchanged. +- 3 - I added owner-aware navigation for the `Public` and `Private` badges so they link to the repository `Settings` page only when the signed-in user is the repository owner. +- 4 - I modified `templates/user/settings/repos.tmpl` so the same visibility badge now appears next to repository names in `/user/settings/repos`, in both list variants rendered by that page. +- 5 - I preserved the existing archived, template, fork, mirror, and object-format indicators so only the requested visibility presentation changed. + +CTX-2026-04-16T00:45:08Z - development - Type: Fixed - Corrected a template rendering error in /user/settings/repos caused by dereferencing a missing Owner object. +- 1 - I fixed `templates/user/settings/repos.tmpl` so the internal-visibility check now guards against a nil `Owner` before accessing `Owner.Visibility`. +- 2 - I applied the null-safe visibility guard in both repository list variants rendered by `/user/settings/repos`. +- 3 - I preserved the new green/red visibility badge styling and owner-aware settings links while removing the nil-pointer render failure. diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl index d938508c21..00fc59636b 100644 --- a/templates/repo/header.tmpl +++ b/templates/repo/header.tmpl @@ -11,19 +11,22 @@ {{.Owner.Name}}/{{.Name}} + {{$settingsLink := printf "%s/settings" $.RepoLink}} + {{$canAccessSettings := and $.IsSigned (eq $.SignedUser.ID .OwnerID)}}
{{if .IsArchived}} {{ctx.Locale.Tr "repo.desc.archived"}}
{{svg "octicon-archive" 18}}
{{end}} {{if .IsPrivate}} - {{ctx.Locale.Tr "repo.desc.private"}} + {{if $canAccessSettings}}{{ctx.Locale.Tr "repo.desc.private"}}{{else}}{{ctx.Locale.Tr "repo.desc.private"}}{{end}}
{{svg "octicon-lock" 18}}
+ {{else if .Owner.Visibility.IsPrivate}} + {{ctx.Locale.Tr "repo.desc.internal"}} +
{{svg "octicon-shield-lock" 18}}
{{else}} - {{if .Owner.Visibility.IsPrivate}} - {{ctx.Locale.Tr "repo.desc.internal"}} -
{{svg "octicon-shield-lock" 18}}
- {{end}} + {{if $canAccessSettings}}{{ctx.Locale.Tr "settings.visibility.public"}}{{else}}{{ctx.Locale.Tr "settings.visibility.public"}}{{end}} +
{{svg "octicon-globe" 18}}
{{end}} {{if $.Permission.HasAnyUnitPublicAccess}} {{ctx.Locale.Tr "repo.desc.public_access"}} diff --git a/templates/shared/repo/list.tmpl b/templates/shared/repo/list.tmpl index 89b4c55b1e..791d539143 100644 --- a/templates/shared/repo/list.tmpl +++ b/templates/shared/repo/list.tmpl @@ -15,16 +15,18 @@ {{.Owner.Name}}/ {{end}} {{.Name}} + {{$settingsLink := printf "%s/settings" .Link}} + {{$canAccessSettings := and $.IsSigned (eq $.SignedUser.ID .OwnerID)}} {{if .IsArchived}} {{ctx.Locale.Tr "repo.desc.archived"}} {{end}} {{if .IsPrivate}} - {{ctx.Locale.Tr "repo.desc.private"}} + {{if $canAccessSettings}}{{ctx.Locale.Tr "repo.desc.private"}}{{else}}{{ctx.Locale.Tr "repo.desc.private"}}{{end}} + {{else if .Owner.Visibility.IsPrivate}} + {{ctx.Locale.Tr "repo.desc.internal"}} {{else}} - {{if .Owner.Visibility.IsPrivate}} - {{ctx.Locale.Tr "repo.desc.internal"}} - {{end}} + {{if $canAccessSettings}}{{ctx.Locale.Tr "settings.visibility.public"}}{{else}}{{ctx.Locale.Tr "settings.visibility.public"}}{{end}} {{end}} {{if .IsTemplate}} {{ctx.Locale.Tr "repo.desc.template"}} diff --git a/templates/user/settings/repos.tmpl b/templates/user/settings/repos.tmpl index e6b7d99bd7..6a85b7acb8 100644 --- a/templates/user/settings/repos.tmpl +++ b/templates/user/settings/repos.tmpl @@ -24,6 +24,15 @@ {{svg "octicon-repo"}} {{end}} {{$repo.OwnerName}}/{{$repo.Name}} + {{$settingsLink := printf "%s/settings" $repo.Link}} + {{$canAccessSettings := and $.IsSigned (eq $.SignedUser.ID $repo.OwnerID)}} + {{if $repo.IsPrivate}} + {{if $canAccessSettings}}{{ctx.Locale.Tr "repo.desc.private"}}{{else}}{{ctx.Locale.Tr "repo.desc.private"}}{{end}} + {{else if and $repo.Owner $repo.Owner.Visibility.IsPrivate}} + {{ctx.Locale.Tr "repo.desc.internal"}} + {{else}} + {{if $canAccessSettings}}{{ctx.Locale.Tr "settings.visibility.public"}}{{else}}{{ctx.Locale.Tr "settings.visibility.public"}}{{end}} + {{end}} {{FileSize $repo.Size}} {{if $repo.IsFork}} {{ctx.Locale.Tr "repo.forked_from"}} @@ -95,6 +104,15 @@ {{svg "octicon-repo"}} {{end}} {{.OwnerName}}/{{.Name}} + {{$settingsLink := printf "%s/settings" .Link}} + {{$canAccessSettings := and $.IsSigned (eq $.SignedUser.ID .OwnerID)}} + {{if .IsPrivate}} + {{if $canAccessSettings}}{{ctx.Locale.Tr "repo.desc.private"}}{{else}}{{ctx.Locale.Tr "repo.desc.private"}}{{end}} + {{else if and .Owner .Owner.Visibility.IsPrivate}} + {{ctx.Locale.Tr "repo.desc.internal"}} + {{else}} + {{if $canAccessSettings}}{{ctx.Locale.Tr "settings.visibility.public"}}{{else}}{{ctx.Locale.Tr "settings.visibility.public"}}{{end}} + {{end}} {{FileSize .Size}} {{if .IsFork}} {{ctx.Locale.Tr "repo.forked_from"}}