From ee130df9cc97554fe0f789649798b94e8bbd9986 Mon Sep 17 00:00:00 2001 From: Bence Kovari Date: Mon, 20 Jul 2026 17:16:07 +0200 Subject: [PATCH 01/19] ahk-web scaffold --- .claude/settings.json | 25 + .vscode/extensions.json | 6 + .vscode/launch.json | 34 + .vscode/tasks.json | 17 + CLAUDE.md | 124 + ahk-backend/.gitignore | 8 + ahk-backend/Ahk.Web.Data/Ahk.Web.Data.csproj | 18 + .../Ahk.Web.Data/ApplicationDbContext.cs | 53 + .../DesignTimeDbContextFactory.cs | 20 + .../Ahk.Web.Data/Entities/ApplicationRole.cs | 16 + .../Ahk.Web.Data/Entities/ApplicationUser.cs | 14 + ahk-backend/Ahk.Web.Data/Entities/Course.cs | 26 + .../Ahk.Web.Data/Entities/CourseMembership.cs | 15 + .../Ahk.Web.Data/Entities/CourseNote.cs | 19 + .../Ahk.Web.Data/Entities/CourseRole.cs | 11 + .../Ahk.Web.Data/Entities/ICourseScoped.cs | 11 + .../Ahk.Web.Data/ICurrentCourseProvider.cs | 16 + .../20260720133652_InitialCreate.Designer.cs | 394 + .../20260720133652_InitialCreate.cs | 310 + .../ApplicationDbContextModelSnapshot.cs | 391 + ahk-backend/Ahk.Web.Data/Roles.cs | 10 + .../Ahk.Web.Data/Seed/DevDataSeeder.cs | 76 + .../Ahk.Web.Server.Tests.csproj | 29 + .../Ahk.Web.Server.Tests/ApiSmokeTests.cs | 71 + .../CourseScopingTests.cs | 73 + .../Admin/CoursesAdminController.cs | 75 + .../Ahk.Web.Server/Admin/Dto/CourseDto.cs | 29 + .../Ahk.Web.Server/Ahk.Web.Server.csproj | 22 + .../Ahk.Web.Server/Auth/AuthController.cs | 100 + .../Auth/Dto/CurrentUserResponse.cs | 26 + .../Ahk.Web.Server/Auth/Dto/LoginRequest.cs | 14 + .../Auth/Dto/RegisterRequest.cs | 18 + .../Auth/ExternalAuthController.cs | 85 + .../Configuration/OidcOptions.cs | 22 + .../CourseMembershipAuthorizationHandler.cs | 50 + .../CourseMembershipRequirement.cs | 9 + .../CourseResolutionMiddleware.cs | 42 + .../CourseContext/CurrentCourseProvider.cs | 14 + .../Courses/CourseProbeController.cs | 62 + ahk-backend/Ahk.Web.Server/Program.cs | 116 + .../Properties/launchSettings.json | 24 + .../appsettings.Development.json | 19 + ahk-backend/Ahk.Web.Server/appsettings.json | 20 + ahk-backend/Ahk.Web.slnx | 5 + ahk-backend/README.md | 54 + ahk-frontend/.editorconfig | 17 + ahk-frontend/.gitignore | 44 + ahk-frontend/.prettierrc | 12 + ahk-frontend/.vscode/extensions.json | 4 + ahk-frontend/.vscode/launch.json | 20 + ahk-frontend/.vscode/mcp.json | 9 + ahk-frontend/.vscode/tasks.json | 42 + ahk-frontend/README.md | 51 + ahk-frontend/angular.json | 83 + ahk-frontend/nswag.json | 33 + ahk-frontend/package-lock.json | 8586 +++++++++++++++++ ahk-frontend/package.json | 34 + ahk-frontend/proxy.conf.js | 11 + ahk-frontend/public/favicon.ico | Bin 0 -> 15086 bytes ahk-frontend/src/app/api/api-client.ts | 804 ++ ahk-frontend/src/app/app.config.ts | 18 + ahk-frontend/src/app/app.html | 1 + ahk-frontend/src/app/app.routes.ts | 40 + ahk-frontend/src/app/app.scss | 0 ahk-frontend/src/app/app.spec.ts | 20 + ahk-frontend/src/app/app.ts | 12 + ahk-frontend/src/app/core/auth/auth.guard.ts | 21 + .../src/app/core/auth/auth.interceptor.ts | 21 + .../src/app/core/auth/auth.service.ts | 70 + .../app/core/course/course-context.service.ts | 24 + .../src/app/core/course/course.guard.ts | 31 + .../app/features/admin/courses/courses.html | 32 + .../app/features/admin/courses/courses.scss | 46 + .../src/app/features/admin/courses/courses.ts | 46 + .../features/course/dashboard/dashboard.html | 24 + .../features/course/dashboard/dashboard.scss | 54 + .../features/course/dashboard/dashboard.ts | 47 + .../src/app/features/login/login.html | 26 + .../src/app/features/login/login.scss | 61 + ahk-frontend/src/app/features/login/login.ts | 54 + ahk-frontend/src/app/layout/shell/shell.html | 36 + ahk-frontend/src/app/layout/shell/shell.scss | 47 + ahk-frontend/src/app/layout/shell/shell.ts | 30 + ahk-frontend/src/index.html | 13 + ahk-frontend/src/main.ts | 6 + ahk-frontend/src/styles.scss | 1 + ahk-frontend/tsconfig.app.json | 15 + ahk-frontend/tsconfig.json | 33 + ahk-frontend/tsconfig.spec.json | 15 + 89 files changed, 13187 insertions(+) create mode 100644 .claude/settings.json create mode 100644 .vscode/extensions.json create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json create mode 100644 CLAUDE.md create mode 100644 ahk-backend/.gitignore create mode 100644 ahk-backend/Ahk.Web.Data/Ahk.Web.Data.csproj create mode 100644 ahk-backend/Ahk.Web.Data/ApplicationDbContext.cs create mode 100644 ahk-backend/Ahk.Web.Data/DesignTimeDbContextFactory.cs create mode 100644 ahk-backend/Ahk.Web.Data/Entities/ApplicationRole.cs create mode 100644 ahk-backend/Ahk.Web.Data/Entities/ApplicationUser.cs create mode 100644 ahk-backend/Ahk.Web.Data/Entities/Course.cs create mode 100644 ahk-backend/Ahk.Web.Data/Entities/CourseMembership.cs create mode 100644 ahk-backend/Ahk.Web.Data/Entities/CourseNote.cs create mode 100644 ahk-backend/Ahk.Web.Data/Entities/CourseRole.cs create mode 100644 ahk-backend/Ahk.Web.Data/Entities/ICourseScoped.cs create mode 100644 ahk-backend/Ahk.Web.Data/ICurrentCourseProvider.cs create mode 100644 ahk-backend/Ahk.Web.Data/Migrations/20260720133652_InitialCreate.Designer.cs create mode 100644 ahk-backend/Ahk.Web.Data/Migrations/20260720133652_InitialCreate.cs create mode 100644 ahk-backend/Ahk.Web.Data/Migrations/ApplicationDbContextModelSnapshot.cs create mode 100644 ahk-backend/Ahk.Web.Data/Roles.cs create mode 100644 ahk-backend/Ahk.Web.Data/Seed/DevDataSeeder.cs create mode 100644 ahk-backend/Ahk.Web.Server.Tests/Ahk.Web.Server.Tests.csproj create mode 100644 ahk-backend/Ahk.Web.Server.Tests/ApiSmokeTests.cs create mode 100644 ahk-backend/Ahk.Web.Server.Tests/CourseScopingTests.cs create mode 100644 ahk-backend/Ahk.Web.Server/Admin/CoursesAdminController.cs create mode 100644 ahk-backend/Ahk.Web.Server/Admin/Dto/CourseDto.cs create mode 100644 ahk-backend/Ahk.Web.Server/Ahk.Web.Server.csproj create mode 100644 ahk-backend/Ahk.Web.Server/Auth/AuthController.cs create mode 100644 ahk-backend/Ahk.Web.Server/Auth/Dto/CurrentUserResponse.cs create mode 100644 ahk-backend/Ahk.Web.Server/Auth/Dto/LoginRequest.cs create mode 100644 ahk-backend/Ahk.Web.Server/Auth/Dto/RegisterRequest.cs create mode 100644 ahk-backend/Ahk.Web.Server/Auth/ExternalAuthController.cs create mode 100644 ahk-backend/Ahk.Web.Server/Configuration/OidcOptions.cs create mode 100644 ahk-backend/Ahk.Web.Server/CourseContext/CourseMembershipAuthorizationHandler.cs create mode 100644 ahk-backend/Ahk.Web.Server/CourseContext/CourseMembershipRequirement.cs create mode 100644 ahk-backend/Ahk.Web.Server/CourseContext/CourseResolutionMiddleware.cs create mode 100644 ahk-backend/Ahk.Web.Server/CourseContext/CurrentCourseProvider.cs create mode 100644 ahk-backend/Ahk.Web.Server/Courses/CourseProbeController.cs create mode 100644 ahk-backend/Ahk.Web.Server/Program.cs create mode 100644 ahk-backend/Ahk.Web.Server/Properties/launchSettings.json create mode 100644 ahk-backend/Ahk.Web.Server/appsettings.Development.json create mode 100644 ahk-backend/Ahk.Web.Server/appsettings.json create mode 100644 ahk-backend/Ahk.Web.slnx create mode 100644 ahk-backend/README.md create mode 100644 ahk-frontend/.editorconfig create mode 100644 ahk-frontend/.gitignore create mode 100644 ahk-frontend/.prettierrc create mode 100644 ahk-frontend/.vscode/extensions.json create mode 100644 ahk-frontend/.vscode/launch.json create mode 100644 ahk-frontend/.vscode/mcp.json create mode 100644 ahk-frontend/.vscode/tasks.json create mode 100644 ahk-frontend/README.md create mode 100644 ahk-frontend/angular.json create mode 100644 ahk-frontend/nswag.json create mode 100644 ahk-frontend/package-lock.json create mode 100644 ahk-frontend/package.json create mode 100644 ahk-frontend/proxy.conf.js create mode 100644 ahk-frontend/public/favicon.ico create mode 100644 ahk-frontend/src/app/api/api-client.ts create mode 100644 ahk-frontend/src/app/app.config.ts create mode 100644 ahk-frontend/src/app/app.html create mode 100644 ahk-frontend/src/app/app.routes.ts create mode 100644 ahk-frontend/src/app/app.scss create mode 100644 ahk-frontend/src/app/app.spec.ts create mode 100644 ahk-frontend/src/app/app.ts create mode 100644 ahk-frontend/src/app/core/auth/auth.guard.ts create mode 100644 ahk-frontend/src/app/core/auth/auth.interceptor.ts create mode 100644 ahk-frontend/src/app/core/auth/auth.service.ts create mode 100644 ahk-frontend/src/app/core/course/course-context.service.ts create mode 100644 ahk-frontend/src/app/core/course/course.guard.ts create mode 100644 ahk-frontend/src/app/features/admin/courses/courses.html create mode 100644 ahk-frontend/src/app/features/admin/courses/courses.scss create mode 100644 ahk-frontend/src/app/features/admin/courses/courses.ts create mode 100644 ahk-frontend/src/app/features/course/dashboard/dashboard.html create mode 100644 ahk-frontend/src/app/features/course/dashboard/dashboard.scss create mode 100644 ahk-frontend/src/app/features/course/dashboard/dashboard.ts create mode 100644 ahk-frontend/src/app/features/login/login.html create mode 100644 ahk-frontend/src/app/features/login/login.scss create mode 100644 ahk-frontend/src/app/features/login/login.ts create mode 100644 ahk-frontend/src/app/layout/shell/shell.html create mode 100644 ahk-frontend/src/app/layout/shell/shell.scss create mode 100644 ahk-frontend/src/app/layout/shell/shell.ts create mode 100644 ahk-frontend/src/index.html create mode 100644 ahk-frontend/src/main.ts create mode 100644 ahk-frontend/src/styles.scss create mode 100644 ahk-frontend/tsconfig.app.json create mode 100644 ahk-frontend/tsconfig.json create mode 100644 ahk-frontend/tsconfig.spec.json diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 00000000..2d676dc0 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,25 @@ +{ + "permissions": { + "allow": [ + "Bash(dotnet add *)", + "Bash(echo \"Moq added \\($?\\)\")", + "Bash(echo \"Mvc.Testing added \\($?\\)\")", + "Bash(echo \"EF InMemory added \\($?\\)\")", + "Bash(dotnet build *)", + "Bash(dotnet test *)", + "Bash(dotnet ef *)", + "Bash(sqllocaldb info *)", + "Bash(npm run *)", + "Bash(curl -sk -o /dev/null -w \"backend /api/auth/me → HTTP %{http_code}\\\\n\" https://localhost:7443/api/auth/me)", + "Bash(curl -sk -o /dev/null -w 'GET / → HTTP %{http_code}\\\\n' https://localhost:4200/)", + "Bash(curl -sk -o /dev/null -w 'HTTP %{http_code}\\\\n' https://localhost:4200/api/auth/me)", + "Bash(curl -sk -c C:/Users/beny314/AppData/Local/Temp/claude/c--Source-ahk-github-automation/8d87f62d-6109-437b-91ea-1cb12635e036/scratchpad/proxy_cookies.txt -X POST https://localhost:4200/api/auth/login -H 'Content-Type: application/json' -d '{\"userName\":\"instructor\",\"password\":\"Instructor123!\"}' -D - -o /dev/null)", + "Bash(echo \"exit=$?\")", + "Bash(MEM=\"C:/Users/beny314/.claude/projects/c--Source-ahk-github-automation/memory\"; ls -la \"$MEM\" 2>/dev/null && echo \"--- MEMORY.md ---\" && cat \"$MEM/MEMORY.md\" 2>/dev/null || echo \"no MEMORY.md yet\")", + "Read(//c/Users/beny314/.claude/projects/c--Source-ahk-github-automation/memory/**)", + "Bash(echo \"=== remaining in memory dir ===\")", + "Bash(ls -A C:/Users/beny314/.claude/projects/c--Source-ahk-github-automation/memory)", + "Bash(echo \"\\(empty\\)\")" + ] + } +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000..c15c9bb5 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "ms-dotnettools.csharp", + "angular.ng-template" + ] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..b956e0d9 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,34 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Backend (ASP.NET Core)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build-backend", + "program": "${workspaceFolder}/ahk-backend/Ahk.Web.Server/bin/Debug/net10.0/Ahk.Web.Server.dll", + "args": [], + "cwd": "${workspaceFolder}/ahk-backend/Ahk.Web.Server", + "stopAtEntry": false, + "console": "integratedTerminal", + "env": { + "ASPNETCORE_ENVIRONMENT": "Development", + "ASPNETCORE_URLS": "https://localhost:7443" + } + }, + { + "name": "Frontend (Angular)", + "type": "node-terminal", + "request": "launch", + "command": "npm start", + "cwd": "${workspaceFolder}/ahk-frontend" + } + ], + "compounds": [ + { + "name": "Full stack (backend + frontend)", + "configurations": ["Backend (ASP.NET Core)", "Frontend (Angular)"], + "stopAll": true + } + ] +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000..88ea0d15 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,17 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build-backend", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/ahk-backend/Ahk.Web.Server/Ahk.Web.Server.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + } + ] +} diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..527a4e35 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,124 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## What this is + +**Ahk** = automated homework evaluation. A toolset that automates homework submission, evaluation, and grading using GitHub, GitHub Classroom, and GitHub Actions. Concept docs: + +The repo is a monorepo of independent applications, each in its own top-level directory with its own solution/module, README, and CI workflows. There is no root-level build — each app builds separately. + +It is mid-transition: the **four original apps** (`github-monitor`, `grade-management`, `review-ui`, `publish-results-pr`) are the production system today, and a **new centralized portal** (`ahk-backend` + `ahk-frontend`) is being built to replace the per-course Azure deployments with a single multi-course site at `ahk.aut.bme.hu`. The portal currently exists as a validated skeleton (auth + course-scoping + codegen); the original apps' functionality has **not** been ported into it yet. When working in this repo, be clear which of the two systems a task targets. + +## The four applications and how they connect + +``` +Student pushes / opens PR + │ + ▼ +GitHub org (managed by GitHub Classroom) + │ webhooks GitHub Actions runs evaluator container + ▼ │ produces result.txt + images +[github-monitor] (.NET Azure Function) ▼ + - enforces workflow rules on repos [publish-results-pr] (Go container) + - /ahk ok chatops approval/grading - formats results as PR comment + │ Azure Queue Storage messages - POSTs results to grade-management + │ │ HMAC-signed HTTP + ▼ ▼ +[grade-management] (.NET Azure Function) ◄───────┘ + - queue-triggered: grade + status events → CosmosDB + - http: evaluation-result webhook, list-grades, list-statuses + │ HTTP API (Function master key) + ▼ +[review-ui] (Blazor WebAssembly, browser-only) + - teacher dashboard of statuses + grades +``` + +Key integration contracts (keep these in sync when changing either side): +- **github-monitor → grade-management**: Azure Queue Storage. Queue names are hard-coded in the `[QueueTrigger(...)]` attributes in `grade-management/.../Functions/**` (e.g. `ahksetgrade`, `ahkconfirmautograde`, `ahkstatustracking*`) and must match what github-monitor's `Services/GradeStore` and `Services/StatusTrackingStore` write. Both sides share duplicated DTO shapes (`Services/.../Dto/*.cs` vs `Functions/.../Dto/*.cs`). +- **publish-results-pr → grade-management**: HMAC-SHA256 signed HTTP to the `evaluation-result` webhook. The signing scheme (verb\nurl\ndate\npayload, base64 HMAC, `X-Ahk-Token`/`X-Ahk-Sha256`/`Date` headers, 10-min skew) is implemented in Go (`internal/publishtoapi`) and validated in .NET (`grade-management/.../Helpers/HmacSha256Validator.cs`). Changing one requires changing the other. See `grade-management/README.md` for the full spec. +- **github-monitor** authenticates to GitHub as a GitHub App per-installation (`Services/GitHubClientFactory`), using Octokit. + +## The new centralized portal (ahk-backend + ahk-frontend) + +Replaces the per-course Azure Function deployments with one site whose domain data is assigned to **Courses** (each course = what used to be a separate deployment, e.g. `viaubc01`). This is **not** multitenant isolation — it's course-scoped data with membership-based authorization. + +- **ahk-backend** — ASP.NET Core **.NET 10** Web API (`Ahk.Web.sln`): `Ahk.Web.Server` (API host), `Ahk.Web.Data` (EF Core + **MSSQL**, ASP.NET Identity, migrations, dev seeder), `Ahk.Web.Server.Tests` (xUnit + Moq). +- **ahk-frontend** — **Angular 21** SPA (standalone components + signals). API clients/DTOs under `src/app/api/` are **NSwag-generated** from the backend's OpenAPI doc — never hand-edit them. + +Design decisions (rationale in the architecture plan and `ahk-backend/README.md`): +- **Auth**: cookie-based ASP.NET Identity (returns 401/403, never redirects) + a **generic OIDC** external provider (config `Authentication:Oidc:*`; disabled when empty). Deliberately **not** `MapIdentityApi` (no OIDC support, bearer-token focus, fixed shapes). +- **Course scoping**: path segment `/api/{course}/...`; `CourseResolutionMiddleware` resolves the `Course` and an `ICurrentCourseProvider` drives an EF Core global query filter over `ICourseScoped` entities; the `CourseMember` authorization policy gates access. Host/admin routes live under `/api/admin/...`. Machine-to-machine endpoints (webhooks / CI callbacks, added during the port) will resolve their course from the payload/token, **not** the path segment. +- **Dev**: both run HTTPS. The Angular dev proxy (`proxy.conf.js`) forwards `/api/*` to the backend so calls are **same-origin — no CORS**, and `API_BASE_URL` is provided as `''` so generated clients issue relative requests. Press F5 with the **"Full stack (backend + frontend)"** compound in `.vscode/launch.json` to start both. +- `CourseProbe` controller + `CourseNote` entity are throwaway scoping probes, removed when real course endpoints land in the port. + +## Build, test, run + +The four original apps target **.NET 6** (Azure Functions v4) except publish-results-pr which is **Go 1.17**. The new portal targets **.NET 10** (ahk-backend) and **Angular 21 / Node** (ahk-frontend). + +### github-monitor / grade-management / review-ui (.NET) +```bash +# from the app directory (github-monitor, grade-management, or review-ui) +dotnet build +dotnet test # run all tests +dotnet test --filter "FullyQualifiedName~HmacSha256ValidatorTest" # single test class +dotnet test --filter "Name=SomeTestMethod" # single test method +``` +- github-monitor and grade-management are Azure Functions — run locally with `func start` (Azure Functions Core Tools) from the function project directory. They need `local.settings.json` (gitignored) supplying the `AHK_*` env vars. +- review-ui: `dotnet run` (or `dotnet watch`) from `review-ui/Ahk.Review.Ui`. It is a standalone WASM app; configure the backend URL in `wwwroot/appsettings.json`. +- Tests use **xUnit + Moq**; handler tests mock the GitHub client, memory cache, and stores (see `Tests/.../Helpers/*MockFactory.cs`). + +### publish-results-pr (Go) +```bash +# from publish-results-pr +go build +go test ./... -test.v +``` +Ships as a container (`Dockerfile`) published to `ghcr.io/akosdudas/ahk-publish-results-pr`, invoked as a GitHub Action step. `.devcontainer` is provided for development. + +### ahk-backend (.NET 10) +```bash +# from ahk-backend +dotnet build +dotnet test # xUnit +dotnet run --project Ahk.Web.Server --launch-profile https # https://localhost:7443, Swagger at /swagger + +# EF Core migrations use the design-time factory in Ahk.Web.Data (both --project and --startup-project point there) +dotnet ef database update --project Ahk.Web.Data --startup-project Ahk.Web.Data +dotnet ef migrations add --project Ahk.Web.Data --startup-project Ahk.Web.Data --output-dir Migrations +``` +Needs MSSQL (LocalDB by default; `ConnectionStrings:Default` in `appsettings.Development.json`). The dev seeder (Development env only) creates `admin`/`Admin123!` (site admin), `instructor`/`Instructor123!` (member of `viaubc01` only), and sample courses `viaubc01`, `viaubb01`. + +### ahk-frontend (Angular 21) +```bash +# from ahk-frontend +npm install +npm start # ng serve --ssl on https://localhost:4200, proxy → https://localhost:7443 +npm run build +npm test # vitest +npm run generate-api # regenerate src/app/api from the backend's OpenAPI (backend must be running) +``` +`nswag.json` pins `"runtime": "Net100"` (the default Net90 binary needs .NET 9, which is not installed here). + +### CI +`.github/workflows/*-build.yaml` build+test each app (path-filtered so only the changed app runs). `*-azure-publish.yaml` / `*-docker-publish.yaml` deploy. Several azure-publish workflows are per-instance (e.g. `VIAUBC01`, `viaubb01`) — deployments are duplicated per course/organization instance. + +## github-monitor architecture (the most complex app) + +- **Entry point**: `GitHubMonitorFunction.cs` — single anonymous HTTP webhook. It validates the `X-Hub-Signature-256` HMAC against `AHK_GitHubWebhookSecret` before doing anything, then hands the raw body to `EventDispatchService`. +- **Dispatch**: `Services/EventDispatch/EventDispatchService` maps a GitHub event name → list of handler types (registered in `Startup.cs` via `EventDispatchConfigBuilder`). Handlers run independently; one throwing is caught and logged, others still run. +- **Handlers**: `EventHandlers/**`. Most extend `RepositoryEventBase`, which: + - deserializes the Octokit payload, + - creates a per-installation `GitHubClient`, + - **short-circuits unless the repo has `.github/ahk-monitor.yml` with `enabled: true`** (cached 12h). New handlers should derive from this base to inherit the enablement gate and the `neptun.txt` / org-membership caching helpers. +- **Two handler families** run side-by-side: rule-enforcement handlers (branch protection, duplicate PR, review→assignee, comment edit/delete, workflow-run limit) and `StatusTracking/**` + `GradeComment/**` handlers that emit events to the queues for grade-management. +- **Store abstraction**: `IGradeStore` / `IStatusTrackingStore` have `*AzureQueue` and `*Noop` implementations. `Startup.cs` wires the Noop variants when `AHK_EventsQueueConnectionString` is absent, so the app runs fully without grade-management. + +## Conventions + +- **Config**: all runtime config comes from `AHK_`-prefixed environment variables (bound via `AddEnvironmentVariables("AHK_")` in github-monitor; direct `AHK_*` names elsewhere). See each app's README for the exact variables. Never commit secrets; `local.settings.json` is gitignored. +- **Enabling a repo for github-monitor**: the repo needs `.github/ahk-monitor.yml` containing `enabled: true` on its default branch, otherwise all its events are ignored. +- **Teacher grading chatops**: `/ahk ok`, `/ahk ok 5`, `/ahk ok 5 3.5 0` in a PR comment approves/merges and records grades (numbers map positionally to exercises). Parsing lives in `Helpers/GradeCommentParser.cs`. +- **Style is enforced at build time**: StyleCop.Analyzers + `EnforceCodeStyleInBuild` + `AnalysisMode=AllEnabledByDefault`, and grade-management/review-ui set `TreatWarningsAsErrors=true`. A large root `.editorconfig` defines the rules — match existing style exactly or the build fails. Match idiom per project (e.g. github-monitor uses explicit namespaces; review-ui uses `ImplicitUsings`/`Nullable` enabled). +- **result.txt evaluation format** (produced by evaluators, parsed by publish-results-pr): lines of `###ahk#taskname#result#comment`, with optional `group@` prefix on taskname for grouped totals. Full spec in `publish-results-pr/README.md`. +- **Portal conventions differ from the original apps**: ahk-backend uses standard ASP.NET config (`appsettings*.json` — `ConnectionStrings:Default`, `Authentication:Oidc:*`), **not** `AHK_` env vars, and uses the default .NET 10 SDK analyzers (no `TreatWarningsAsErrors`), so it is not bound by the root `.editorconfig`'s StyleCop rules. ahk-frontend follows the Angular style (2-space, standalone components + signals). diff --git a/ahk-backend/.gitignore b/ahk-backend/.gitignore new file mode 100644 index 00000000..c2c37064 --- /dev/null +++ b/ahk-backend/.gitignore @@ -0,0 +1,8 @@ +## Build output +bin/ +obj/ + +## Local/dev secrets (never commit) +appsettings.*.local.json +local.settings.json +*.user diff --git a/ahk-backend/Ahk.Web.Data/Ahk.Web.Data.csproj b/ahk-backend/Ahk.Web.Data/Ahk.Web.Data.csproj new file mode 100644 index 00000000..ddb40d70 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Ahk.Web.Data.csproj @@ -0,0 +1,18 @@ + + + + net10.0 + enable + enable + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + diff --git a/ahk-backend/Ahk.Web.Data/ApplicationDbContext.cs b/ahk-backend/Ahk.Web.Data/ApplicationDbContext.cs new file mode 100644 index 00000000..0b4d740c --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/ApplicationDbContext.cs @@ -0,0 +1,53 @@ +using Ahk.Web.Data.Entities; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; + +namespace Ahk.Web.Data; + +/// +/// EF Core context backing ASP.NET Identity plus the course model. Applies a global query filter on every +/// entity so a request only sees rows for the resolved current course. +/// +public class ApplicationDbContext : IdentityDbContext +{ + private readonly ICurrentCourseProvider currentCourse; + + public ApplicationDbContext(DbContextOptions options, ICurrentCourseProvider currentCourse) + : base(options) + { + this.currentCourse = currentCourse; + } + + public DbSet Courses => Set(); + + public DbSet CourseMemberships => Set(); + + public DbSet CourseNotes => Set(); + + protected override void OnModelCreating(ModelBuilder builder) + { + base.OnModelCreating(builder); + + builder.Entity(e => + { + e.HasIndex(c => c.Slug).IsUnique(); + e.Property(c => c.Slug).HasMaxLength(64).IsRequired(); + e.Property(c => c.Name).HasMaxLength(256).IsRequired(); + }); + + builder.Entity(e => + { + e.HasKey(m => new { m.UserId, m.CourseId }); + e.HasOne(m => m.User).WithMany(u => u.CourseMemberships).HasForeignKey(m => m.UserId).OnDelete(DeleteBehavior.Cascade); + e.HasOne(m => m.Course).WithMany(c => c.Memberships).HasForeignKey(m => m.CourseId).OnDelete(DeleteBehavior.Cascade); + }); + + builder.Entity(e => + { + e.Property(n => n.Text).HasMaxLength(1024).IsRequired(); + e.HasOne(n => n.Course).WithMany().HasForeignKey(n => n.CourseId).OnDelete(DeleteBehavior.Cascade); + // Course-scoping filter: only rows for the request's current course are visible. + e.HasQueryFilter(n => n.CourseId == this.currentCourse.CurrentCourseId); + }); + } +} diff --git a/ahk-backend/Ahk.Web.Data/DesignTimeDbContextFactory.cs b/ahk-backend/Ahk.Web.Data/DesignTimeDbContextFactory.cs new file mode 100644 index 00000000..1409c30b --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/DesignTimeDbContextFactory.cs @@ -0,0 +1,20 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; + +namespace Ahk.Web.Data; + +/// +/// Lets dotnet ef build the context directly from this project (no web host needed). Uses a +/// LocalDB design-time connection; the runtime connection string comes from configuration in the web app. +/// +public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory +{ + public ApplicationDbContext CreateDbContext(string[] args) + { + var options = new DbContextOptionsBuilder() + .UseSqlServer("Server=(localdb)\\MSSQLLocalDB;Database=AhkWeb;Trusted_Connection=True;TrustServerCertificate=True") + .Options; + + return new ApplicationDbContext(options, new NullCurrentCourseProvider()); + } +} diff --git a/ahk-backend/Ahk.Web.Data/Entities/ApplicationRole.cs b/ahk-backend/Ahk.Web.Data/Entities/ApplicationRole.cs new file mode 100644 index 00000000..15ab8e88 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Entities/ApplicationRole.cs @@ -0,0 +1,16 @@ +using Microsoft.AspNetCore.Identity; + +namespace Ahk.Web.Data.Entities; + +/// Application-wide (site-level) role, e.g. the super-admin role. Course-level roles live on . +public class ApplicationRole : IdentityRole +{ + public ApplicationRole() + { + } + + public ApplicationRole(string roleName) + : base(roleName) + { + } +} diff --git a/ahk-backend/Ahk.Web.Data/Entities/ApplicationUser.cs b/ahk-backend/Ahk.Web.Data/Entities/ApplicationUser.cs new file mode 100644 index 00000000..49f130f9 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Entities/ApplicationUser.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Identity; + +namespace Ahk.Web.Data.Entities; + +/// +/// Application user. Extends the ASP.NET Identity user with app-specific profile fields. +/// A user may be a member of many s via . +/// +public class ApplicationUser : IdentityUser +{ + public string? DisplayName { get; set; } + + public ICollection CourseMemberships { get; } = new List(); +} diff --git a/ahk-backend/Ahk.Web.Data/Entities/Course.cs b/ahk-backend/Ahk.Web.Data/Entities/Course.cs new file mode 100644 index 00000000..a679d955 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Entities/Course.cs @@ -0,0 +1,26 @@ +namespace Ahk.Web.Data.Entities; + +/// +/// A university course (e.g. BME subject code "viaubc01"). This is what used to be a separate +/// per-course Azure Functions deployment; each course now lives as one record in the central site +/// and holds its own GitHub-environment configuration. Domain data is assigned to a course via +/// . +/// +public class Course +{ + public Guid Id { get; set; } = Guid.NewGuid(); + + /// URL-safe unique identifier used in the path segment: ahk.aut.bme.hu/{Slug}/... + public string Slug { get; set; } = string.Empty; + + public string Name { get; set; } = string.Empty; + + public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; + + // --- Placeholders for the GitHub-environment config ported from the per-course Azure deployments. --- + // Populated in the porting milestone (GitHub App id/private key, webhook secret, queue/connection + // settings, etc.). Kept nullable so the skeleton runs before the port. + public string? GitHubOrganization { get; set; } + + public ICollection Memberships { get; } = new List(); +} diff --git a/ahk-backend/Ahk.Web.Data/Entities/CourseMembership.cs b/ahk-backend/Ahk.Web.Data/Entities/CourseMembership.cs new file mode 100644 index 00000000..75541128 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Entities/CourseMembership.cs @@ -0,0 +1,15 @@ +namespace Ahk.Web.Data.Entities; + +/// Assigns a user to a course with a course-level role. A user may belong to many courses. +public class CourseMembership +{ + public string UserId { get; set; } = string.Empty; + + public Guid CourseId { get; set; } + + public CourseRole Role { get; set; } = CourseRole.Instructor; + + public ApplicationUser? User { get; set; } + + public Course? Course { get; set; } +} diff --git a/ahk-backend/Ahk.Web.Data/Entities/CourseNote.cs b/ahk-backend/Ahk.Web.Data/Entities/CourseNote.cs new file mode 100644 index 00000000..5fc1577b --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Entities/CourseNote.cs @@ -0,0 +1,19 @@ +namespace Ahk.Web.Data.Entities; + +/// +/// Temporary probe entity used only to verify course-scoping end-to-end in this skeleton milestone. +/// It is the first type; real domain entities (grades, statuses, submissions) +/// replace it during the port, and this type is then removed. +/// +public class CourseNote : ICourseScoped +{ + public Guid Id { get; set; } = Guid.NewGuid(); + + public Guid CourseId { get; set; } + + public string Text { get; set; } = string.Empty; + + public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; + + public Course? Course { get; set; } +} diff --git a/ahk-backend/Ahk.Web.Data/Entities/CourseRole.cs b/ahk-backend/Ahk.Web.Data/Entities/CourseRole.cs new file mode 100644 index 00000000..9459cd90 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Entities/CourseRole.cs @@ -0,0 +1,11 @@ +namespace Ahk.Web.Data.Entities; + +/// Role a user holds within a specific course (distinct from site-level roles). +public enum CourseRole +{ + /// Can view the course's submissions, statuses and grades. + Instructor = 0, + + /// Can additionally manage the course's configuration and members. + Admin = 1, +} diff --git a/ahk-backend/Ahk.Web.Data/Entities/ICourseScoped.cs b/ahk-backend/Ahk.Web.Data/Entities/ICourseScoped.cs new file mode 100644 index 00000000..904b323f --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Entities/ICourseScoped.cs @@ -0,0 +1,11 @@ +namespace Ahk.Web.Data.Entities; + +/// +/// Marker for domain entities whose rows belong to a single course. The +/// applies an EF Core global query filter on so queries only see the active course's +/// rows. Authorization (course membership) remains the real access gate; the filter is a scoping convenience. +/// +public interface ICourseScoped +{ + Guid CourseId { get; } +} diff --git a/ahk-backend/Ahk.Web.Data/ICurrentCourseProvider.cs b/ahk-backend/Ahk.Web.Data/ICurrentCourseProvider.cs new file mode 100644 index 00000000..b38a3ddf --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/ICurrentCourseProvider.cs @@ -0,0 +1,16 @@ +namespace Ahk.Web.Data; + +/// +/// Supplies the course the current request is scoped to. Implemented in the web layer (resolved from the +/// {course} route segment) and consumed by to drive the course query filter. +/// +public interface ICurrentCourseProvider +{ + Guid? CurrentCourseId { get; } +} + +/// No-op provider (no active course). Used at design time and in host/admin contexts. +public sealed class NullCurrentCourseProvider : ICurrentCourseProvider +{ + public Guid? CurrentCourseId => null; +} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260720133652_InitialCreate.Designer.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260720133652_InitialCreate.Designer.cs new file mode 100644 index 00000000..367e5c68 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Migrations/20260720133652_InitialCreate.Designer.cs @@ -0,0 +1,394 @@ +// +using System; +using Ahk.Web.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Ahk.Web.Data.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20260720133652_InitialCreate")] + partial class InitialCreate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationRole", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("GitHubOrganization") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("CourseId") + .HasColumnType("uniqueidentifier"); + + b.Property("Role") + .HasColumnType("int"); + + b.HasKey("UserId", "CourseId"); + + b.HasIndex("CourseId"); + + b.ToTable("CourseMemberships"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseNote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CourseId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.ToTable("CourseNotes"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("RoleId") + .HasColumnType("nvarchar(450)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany("Memberships") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", "User") + .WithMany("CourseMemberships") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseNote", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => + { + b.Navigation("CourseMemberships"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => + { + b.Navigation("Memberships"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260720133652_InitialCreate.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260720133652_InitialCreate.cs new file mode 100644 index 00000000..1b891886 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Migrations/20260720133652_InitialCreate.cs @@ -0,0 +1,310 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ahk.Web.Data.Migrations +{ + /// + public partial class InitialCreate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AspNetRoles", + columns: table => new + { + Id = table.Column(type: "nvarchar(450)", nullable: false), + Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + NormalizedName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetUsers", + columns: table => new + { + Id = table.Column(type: "nvarchar(450)", nullable: false), + DisplayName = table.Column(type: "nvarchar(max)", nullable: true), + UserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + NormalizedUserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + Email = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + NormalizedEmail = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + EmailConfirmed = table.Column(type: "bit", nullable: false), + PasswordHash = table.Column(type: "nvarchar(max)", nullable: true), + SecurityStamp = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true), + PhoneNumber = table.Column(type: "nvarchar(max)", nullable: true), + PhoneNumberConfirmed = table.Column(type: "bit", nullable: false), + TwoFactorEnabled = table.Column(type: "bit", nullable: false), + LockoutEnd = table.Column(type: "datetimeoffset", nullable: true), + LockoutEnabled = table.Column(type: "bit", nullable: false), + AccessFailedCount = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUsers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Courses", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Slug = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + CreatedAt = table.Column(type: "datetimeoffset", nullable: false), + GitHubOrganization = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Courses", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetRoleClaims", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + RoleId = table.Column(type: "nvarchar(450)", nullable: false), + ClaimType = table.Column(type: "nvarchar(max)", nullable: true), + ClaimValue = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserClaims", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + UserId = table.Column(type: "nvarchar(450)", nullable: false), + ClaimType = table.Column(type: "nvarchar(max)", nullable: true), + ClaimValue = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetUserClaims_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserLogins", + columns: table => new + { + LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), + ProviderKey = table.Column(type: "nvarchar(450)", nullable: false), + ProviderDisplayName = table.Column(type: "nvarchar(max)", nullable: true), + UserId = table.Column(type: "nvarchar(450)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_AspNetUserLogins_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserRoles", + columns: table => new + { + UserId = table.Column(type: "nvarchar(450)", nullable: false), + RoleId = table.Column(type: "nvarchar(450)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserTokens", + columns: table => new + { + UserId = table.Column(type: "nvarchar(450)", nullable: false), + LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), + Name = table.Column(type: "nvarchar(450)", nullable: false), + Value = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_AspNetUserTokens_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "CourseMemberships", + columns: table => new + { + UserId = table.Column(type: "nvarchar(450)", nullable: false), + CourseId = table.Column(type: "uniqueidentifier", nullable: false), + Role = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CourseMemberships", x => new { x.UserId, x.CourseId }); + table.ForeignKey( + name: "FK_CourseMemberships_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_CourseMemberships_Courses_CourseId", + column: x => x.CourseId, + principalTable: "Courses", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "CourseNotes", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + CourseId = table.Column(type: "uniqueidentifier", nullable: false), + Text = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: false), + CreatedAt = table.Column(type: "datetimeoffset", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CourseNotes", x => x.Id); + table.ForeignKey( + name: "FK_CourseNotes_Courses_CourseId", + column: x => x.CourseId, + principalTable: "Courses", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_AspNetRoleClaims_RoleId", + table: "AspNetRoleClaims", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "RoleNameIndex", + table: "AspNetRoles", + column: "NormalizedName", + unique: true, + filter: "[NormalizedName] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserClaims_UserId", + table: "AspNetUserClaims", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserLogins_UserId", + table: "AspNetUserLogins", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserRoles_RoleId", + table: "AspNetUserRoles", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "AspNetUsers", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "AspNetUsers", + column: "NormalizedUserName", + unique: true, + filter: "[NormalizedUserName] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_CourseMemberships_CourseId", + table: "CourseMemberships", + column: "CourseId"); + + migrationBuilder.CreateIndex( + name: "IX_CourseNotes_CourseId", + table: "CourseNotes", + column: "CourseId"); + + migrationBuilder.CreateIndex( + name: "IX_Courses_Slug", + table: "Courses", + column: "Slug", + unique: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AspNetRoleClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserLogins"); + + migrationBuilder.DropTable( + name: "AspNetUserRoles"); + + migrationBuilder.DropTable( + name: "AspNetUserTokens"); + + migrationBuilder.DropTable( + name: "CourseMemberships"); + + migrationBuilder.DropTable( + name: "CourseNotes"); + + migrationBuilder.DropTable( + name: "AspNetRoles"); + + migrationBuilder.DropTable( + name: "AspNetUsers"); + + migrationBuilder.DropTable( + name: "Courses"); + } + } +} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/ApplicationDbContextModelSnapshot.cs b/ahk-backend/Ahk.Web.Data/Migrations/ApplicationDbContextModelSnapshot.cs new file mode 100644 index 00000000..90b3dd64 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Migrations/ApplicationDbContextModelSnapshot.cs @@ -0,0 +1,391 @@ +// +using System; +using Ahk.Web.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Ahk.Web.Data.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + partial class ApplicationDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationRole", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("GitHubOrganization") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("CourseId") + .HasColumnType("uniqueidentifier"); + + b.Property("Role") + .HasColumnType("int"); + + b.HasKey("UserId", "CourseId"); + + b.HasIndex("CourseId"); + + b.ToTable("CourseMemberships"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseNote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CourseId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.ToTable("CourseNotes"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("RoleId") + .HasColumnType("nvarchar(450)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany("Memberships") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", "User") + .WithMany("CourseMemberships") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseNote", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => + { + b.Navigation("CourseMemberships"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => + { + b.Navigation("Memberships"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ahk-backend/Ahk.Web.Data/Roles.cs b/ahk-backend/Ahk.Web.Data/Roles.cs new file mode 100644 index 00000000..23e168a0 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Roles.cs @@ -0,0 +1,10 @@ +namespace Ahk.Web.Data; + +/// Site-level (application-wide) role names. Course-level roles are on the membership record. +public static class Roles +{ + /// Super-admin: manages courses and their connected GitHub environments across the whole site. + public const string Admin = "Admin"; + + public static readonly IReadOnlyList All = new[] { Admin }; +} diff --git a/ahk-backend/Ahk.Web.Data/Seed/DevDataSeeder.cs b/ahk-backend/Ahk.Web.Data/Seed/DevDataSeeder.cs new file mode 100644 index 00000000..a604389a --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Seed/DevDataSeeder.cs @@ -0,0 +1,76 @@ +using Ahk.Web.Data.Entities; +using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; + +namespace Ahk.Web.Data.Seed; + +/// +/// Seeds development data: applies migrations, ensures roles, a super-admin, two sample courses, a membership +/// in only one of them, and a probe note per course — enough to exercise auth and course-scoping locally. +/// +public static class DevDataSeeder +{ + public const string AdminUserName = "admin"; + public const string AdminPassword = "Admin123!"; + + public static async Task SeedAsync(IServiceProvider services) + { + using var scope = services.CreateScope(); + var sp = scope.ServiceProvider; + + var db = sp.GetRequiredService(); + await db.Database.MigrateAsync(); + + var roleManager = sp.GetRequiredService>(); + foreach (var role in Roles.All) + { + if (!await roleManager.RoleExistsAsync(role)) + await roleManager.CreateAsync(new ApplicationRole(role)); + } + + var userManager = sp.GetRequiredService>(); + var admin = await userManager.FindByNameAsync(AdminUserName); + if (admin is null) + { + admin = new ApplicationUser { UserName = AdminUserName, Email = "admin@ahk.aut.bme.hu", DisplayName = "Site Admin", EmailConfirmed = true }; + await userManager.CreateAsync(admin, AdminPassword); + await userManager.AddToRoleAsync(admin, Roles.Admin); + } + + // A non-admin instructor who is a member of exactly one course (used to verify course-scoping / 403s). + var instructor = await userManager.FindByNameAsync("instructor"); + if (instructor is null) + { + instructor = new ApplicationUser { UserName = "instructor", Email = "instructor@ahk.aut.bme.hu", DisplayName = "Sample Instructor", EmailConfirmed = true }; + await userManager.CreateAsync(instructor, "Instructor123!"); + } + + var seedCourses = new[] + { + new Course { Slug = "viaubc01", Name = "Sample Course VIAUBC01" }, + new Course { Slug = "viaubb01", Name = "Sample Course VIAUBB01" }, + }; + + foreach (var course in seedCourses) + { + var existing = await db.Courses.FirstOrDefaultAsync(c => c.Slug == course.Slug); + if (existing is null) + { + db.Courses.Add(course); + db.CourseNotes.Add(new CourseNote { CourseId = course.Id, Text = $"Probe note for {course.Slug}" }); + } + } + + await db.SaveChangesAsync(); + + // Instructor is a member of the first course only. + var firstCourse = await db.Courses.FirstAsync(c => c.Slug == "viaubc01"); + var hasMembership = await db.CourseMemberships.AnyAsync(m => m.UserId == instructor.Id && m.CourseId == firstCourse.Id); + if (!hasMembership) + { + db.CourseMemberships.Add(new CourseMembership { UserId = instructor.Id, CourseId = firstCourse.Id, Role = CourseRole.Instructor }); + await db.SaveChangesAsync(); + } + } +} diff --git a/ahk-backend/Ahk.Web.Server.Tests/Ahk.Web.Server.Tests.csproj b/ahk-backend/Ahk.Web.Server.Tests/Ahk.Web.Server.Tests.csproj new file mode 100644 index 00000000..4e3a9e19 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server.Tests/Ahk.Web.Server.Tests.csproj @@ -0,0 +1,29 @@ + + + + net10.0 + enable + enable + false + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ahk-backend/Ahk.Web.Server.Tests/ApiSmokeTests.cs b/ahk-backend/Ahk.Web.Server.Tests/ApiSmokeTests.cs new file mode 100644 index 00000000..51591ed3 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server.Tests/ApiSmokeTests.cs @@ -0,0 +1,71 @@ +using System.Linq; +using System.Net; +using Ahk.Web.Data; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Xunit; + +namespace Ahk.Web.Server.Tests; + +/// +/// Boots the real pipeline (auth + controllers + course middleware) with the SQL Server DbContext swapped for +/// an in-memory one, and checks the fundamental contracts hold without a database or authenticated user. +/// +public class ApiSmokeTests : IClassFixture +{ + private readonly TestAppFactory factory; + + public ApiSmokeTests(TestAppFactory factory) => this.factory = factory; + + [Fact] + public async Task Me_WithoutAuth_Returns401() + { + var client = factory.CreateClient(); + var response = await client.GetAsync("/api/auth/me"); + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); + } + + [Fact] + public async Task AdminCourses_WithoutAuth_Returns401() + { + var client = factory.CreateClient(); + var response = await client.GetAsync("/api/admin/courses"); + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); + } + + [Fact] + public async Task UnknownCourseSlug_Returns404_BeforeAuth() + { + var client = factory.CreateClient(); + var response = await client.GetAsync("/api/no-such-course/probe/notes"); + Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); + } + + public sealed class TestAppFactory : WebApplicationFactory + { + protected override IHost CreateHost(IHostBuilder builder) + { + // "Testing" (not Development) so the dev data seeder / SQL Server connection are skipped. + builder.UseEnvironment("Testing"); + builder.ConfigureServices(services => + { + // Drop the SqlServer registration (the options, EF's options-configuration, and the context) + // before swapping in the in-memory provider, otherwise two providers end up registered. + var toRemove = services.Where(d => + d.ServiceType == typeof(DbContextOptions) || + d.ServiceType == typeof(DbContextOptions) || + d.ServiceType == typeof(ApplicationDbContext) || + (d.ServiceType.IsGenericType && d.ServiceType.Name.StartsWith("IDbContextOptionsConfiguration", StringComparison.Ordinal))) + .ToList(); + foreach (var descriptor in toRemove) + services.Remove(descriptor); + + services.AddDbContext(options => options.UseInMemoryDatabase("ApiSmokeTests")); + }); + + return base.CreateHost(builder); + } + } +} diff --git a/ahk-backend/Ahk.Web.Server.Tests/CourseScopingTests.cs b/ahk-backend/Ahk.Web.Server.Tests/CourseScopingTests.cs new file mode 100644 index 00000000..157587f4 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server.Tests/CourseScopingTests.cs @@ -0,0 +1,73 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Microsoft.EntityFrameworkCore; +using Xunit; + +namespace Ahk.Web.Server.Tests; + +/// +/// Verifies the EF Core course query filter: a request scoped to one course only sees that course's rows. +/// This is the core isolation mechanism, so it is exercised directly against the DbContext. +/// +public class CourseScopingTests +{ + private sealed class MutableCourseProvider : ICurrentCourseProvider + { + public Guid? CurrentCourseId { get; set; } + } + + private static ApplicationDbContext CreateContext(ICurrentCourseProvider provider, string dbName) + { + var options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(dbName) + .Options; + return new ApplicationDbContext(options, provider); + } + + [Fact] + public async Task CourseNotes_AreFilteredToTheCurrentCourse() + { + var dbName = Guid.NewGuid().ToString(); + var courseA = Guid.NewGuid(); + var courseB = Guid.NewGuid(); + + // Seed notes for two courses using an unscoped provider (null → filter matches nothing, so use raw add). + var seedProvider = new MutableCourseProvider { CurrentCourseId = null }; + await using (var seed = CreateContext(seedProvider, dbName)) + { + seed.CourseNotes.Add(new CourseNote { CourseId = courseA, Text = "A1" }); + seed.CourseNotes.Add(new CourseNote { CourseId = courseA, Text = "A2" }); + seed.CourseNotes.Add(new CourseNote { CourseId = courseB, Text = "B1" }); + await seed.SaveChangesAsync(); + } + + var provider = new MutableCourseProvider { CurrentCourseId = courseA }; + await using (var scoped = CreateContext(provider, dbName)) + { + var notes = await scoped.CourseNotes.ToListAsync(); + Assert.Equal(2, notes.Count); + Assert.All(notes, n => Assert.Equal(courseA, n.CourseId)); + } + + provider.CurrentCourseId = courseB; + await using (var scoped = CreateContext(provider, dbName)) + { + var notes = await scoped.CourseNotes.ToListAsync(); + Assert.Single(notes); + Assert.Equal("B1", notes[0].Text); + } + } + + [Fact] + public async Task CourseNotes_AreHiddenWhenNoCourseIsResolved() + { + var dbName = Guid.NewGuid().ToString(); + var provider = new MutableCourseProvider { CurrentCourseId = null }; + await using var db = CreateContext(provider, dbName); + + db.CourseNotes.Add(new CourseNote { CourseId = Guid.NewGuid(), Text = "orphan" }); + await db.SaveChangesAsync(); + + Assert.Empty(await db.CourseNotes.ToListAsync()); + } +} diff --git a/ahk-backend/Ahk.Web.Server/Admin/CoursesAdminController.cs b/ahk-backend/Ahk.Web.Server/Admin/CoursesAdminController.cs new file mode 100644 index 00000000..a396c710 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Admin/CoursesAdminController.cs @@ -0,0 +1,75 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Ahk.Web.Server.Admin.Dto; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace Ahk.Web.Server.Admin; + +/// +/// Host/admin context (no {course} segment): site super-admins manage the set of courses and, later, their +/// connected GitHub environments. This centralizes what used to be a separate per-course Azure deployment. +/// +[ApiController] +[Route("api/admin/courses")] +[Authorize(Roles = Roles.Admin)] +public sealed class CoursesAdminController : ControllerBase +{ + private readonly ApplicationDbContext db; + + public CoursesAdminController(ApplicationDbContext db) => this.db = db; + + [HttpGet] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + public async Task>> List() + { + var courses = await db.Courses + .AsNoTracking() + .OrderBy(c => c.Slug) + .Select(c => new CourseDto + { + Id = c.Id, + Slug = c.Slug, + Name = c.Name, + GitHubOrganization = c.GitHubOrganization, + CreatedAt = c.CreatedAt, + }) + .ToListAsync(); + + return Ok(courses); + } + + [HttpGet("{id:guid}")] + [ProducesResponseType(typeof(CourseDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> Get(Guid id) + { + var course = await db.Courses.AsNoTracking().FirstOrDefaultAsync(c => c.Id == id); + return course is null ? NotFound() : Ok(ToDto(course)); + } + + [HttpPost] + [ProducesResponseType(typeof(CourseDto), StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status409Conflict)] + public async Task> Create([FromBody] CreateCourseRequest request) + { + if (await db.Courses.AnyAsync(c => c.Slug == request.Slug)) + return Conflict(new { error = $"A course with slug '{request.Slug}' already exists." }); + + var course = new Course { Slug = request.Slug, Name = request.Name, GitHubOrganization = request.GitHubOrganization }; + db.Courses.Add(course); + await db.SaveChangesAsync(); + + return CreatedAtAction(nameof(Get), new { id = course.Id }, ToDto(course)); + } + + private static CourseDto ToDto(Course c) => new() + { + Id = c.Id, + Slug = c.Slug, + Name = c.Name, + GitHubOrganization = c.GitHubOrganization, + CreatedAt = c.CreatedAt, + }; +} diff --git a/ahk-backend/Ahk.Web.Server/Admin/Dto/CourseDto.cs b/ahk-backend/Ahk.Web.Server/Admin/Dto/CourseDto.cs new file mode 100644 index 00000000..6ca6e074 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Admin/Dto/CourseDto.cs @@ -0,0 +1,29 @@ +using System.ComponentModel.DataAnnotations; + +namespace Ahk.Web.Server.Admin.Dto; + +public sealed class CourseDto +{ + public Guid Id { get; set; } + + public string Slug { get; set; } = string.Empty; + + public string Name { get; set; } = string.Empty; + + public string? GitHubOrganization { get; set; } + + public DateTimeOffset CreatedAt { get; set; } +} + +public sealed class CreateCourseRequest +{ + [Required] + [RegularExpression("^[a-z0-9-]{2,64}$", ErrorMessage = "Slug must be 2-64 chars: lowercase letters, digits, hyphen.")] + public string Slug { get; set; } = string.Empty; + + [Required] + [MaxLength(256)] + public string Name { get; set; } = string.Empty; + + public string? GitHubOrganization { get; set; } +} diff --git a/ahk-backend/Ahk.Web.Server/Ahk.Web.Server.csproj b/ahk-backend/Ahk.Web.Server/Ahk.Web.Server.csproj new file mode 100644 index 00000000..73169844 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Ahk.Web.Server.csproj @@ -0,0 +1,22 @@ + + + + net10.0 + enable + enable + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + diff --git a/ahk-backend/Ahk.Web.Server/Auth/AuthController.cs b/ahk-backend/Ahk.Web.Server/Auth/AuthController.cs new file mode 100644 index 00000000..e04c15ee --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Auth/AuthController.cs @@ -0,0 +1,100 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Ahk.Web.Server.Auth.Dto; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace Ahk.Web.Server.Auth; + +/// Local username/password authentication and the current-user endpoint for the SPA. +[ApiController] +[Route("api/auth")] +public sealed class AuthController : ControllerBase +{ + private readonly SignInManager signInManager; + private readonly UserManager userManager; + private readonly ApplicationDbContext db; + + public AuthController(SignInManager signInManager, UserManager userManager, ApplicationDbContext db) + { + this.signInManager = signInManager; + this.userManager = userManager; + this.db = db; + } + + [HttpPost("login")] + [ProducesResponseType(typeof(CurrentUserResponse), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + public async Task> Login([FromBody] LoginRequest request) + { + var result = await signInManager.PasswordSignInAsync(request.UserName, request.Password, request.RememberMe, lockoutOnFailure: true); + if (!result.Succeeded) + return Unauthorized(); + + var user = await userManager.FindByNameAsync(request.UserName); + return Ok(await BuildCurrentUserAsync(user!)); + } + + [HttpPost("logout")] + [Authorize] + [ProducesResponseType(StatusCodes.Status204NoContent)] + public async Task Logout() + { + await signInManager.SignOutAsync(); + return NoContent(); + } + + [HttpPost("register")] + [ProducesResponseType(typeof(CurrentUserResponse), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public async Task> Register([FromBody] RegisterRequest request) + { + var user = new ApplicationUser { UserName = request.UserName, Email = request.Email, DisplayName = request.DisplayName }; + var result = await userManager.CreateAsync(user, request.Password); + if (!result.Succeeded) + return BadRequest(new { errors = result.Errors.Select(e => e.Description) }); + + await signInManager.SignInAsync(user, isPersistent: false); + return Ok(await BuildCurrentUserAsync(user)); + } + + [HttpGet("me")] + [Authorize] + [ProducesResponseType(typeof(CurrentUserResponse), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + public async Task> Me() + { + var user = await userManager.GetUserAsync(User); + if (user is null) + return Unauthorized(); + + return Ok(await BuildCurrentUserAsync(user)); + } + + private async Task BuildCurrentUserAsync(ApplicationUser user) + { + var roles = await userManager.GetRolesAsync(user); + var courses = await db.CourseMemberships + .AsNoTracking() + .Where(m => m.UserId == user.Id) + .Select(m => new CourseMembershipDto + { + Slug = m.Course!.Slug, + Name = m.Course.Name, + Role = m.Role.ToString(), + }) + .ToListAsync(); + + return new CurrentUserResponse + { + UserId = user.Id, + UserName = user.UserName ?? string.Empty, + Email = user.Email, + DisplayName = user.DisplayName, + Roles = roles.ToList(), + Courses = courses, + }; + } +} diff --git a/ahk-backend/Ahk.Web.Server/Auth/Dto/CurrentUserResponse.cs b/ahk-backend/Ahk.Web.Server/Auth/Dto/CurrentUserResponse.cs new file mode 100644 index 00000000..8db6a4ab --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Auth/Dto/CurrentUserResponse.cs @@ -0,0 +1,26 @@ +namespace Ahk.Web.Server.Auth.Dto; + +/// Shape returned by GET /api/auth/me — hydrates the SPA session with identity + course access. +public sealed class CurrentUserResponse +{ + public string UserId { get; set; } = string.Empty; + + public string UserName { get; set; } = string.Empty; + + public string? Email { get; set; } + + public string? DisplayName { get; set; } + + public IReadOnlyList Roles { get; set; } = Array.Empty(); + + public IReadOnlyList Courses { get; set; } = Array.Empty(); +} + +public sealed class CourseMembershipDto +{ + public string Slug { get; set; } = string.Empty; + + public string Name { get; set; } = string.Empty; + + public string Role { get; set; } = string.Empty; +} diff --git a/ahk-backend/Ahk.Web.Server/Auth/Dto/LoginRequest.cs b/ahk-backend/Ahk.Web.Server/Auth/Dto/LoginRequest.cs new file mode 100644 index 00000000..2a18bd16 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Auth/Dto/LoginRequest.cs @@ -0,0 +1,14 @@ +using System.ComponentModel.DataAnnotations; + +namespace Ahk.Web.Server.Auth.Dto; + +public sealed class LoginRequest +{ + [Required] + public string UserName { get; set; } = string.Empty; + + [Required] + public string Password { get; set; } = string.Empty; + + public bool RememberMe { get; set; } +} diff --git a/ahk-backend/Ahk.Web.Server/Auth/Dto/RegisterRequest.cs b/ahk-backend/Ahk.Web.Server/Auth/Dto/RegisterRequest.cs new file mode 100644 index 00000000..be809ccb --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Auth/Dto/RegisterRequest.cs @@ -0,0 +1,18 @@ +using System.ComponentModel.DataAnnotations; + +namespace Ahk.Web.Server.Auth.Dto; + +public sealed class RegisterRequest +{ + [Required] + public string UserName { get; set; } = string.Empty; + + [Required] + [EmailAddress] + public string Email { get; set; } = string.Empty; + + [Required] + public string Password { get; set; } = string.Empty; + + public string? DisplayName { get; set; } +} diff --git a/ahk-backend/Ahk.Web.Server/Auth/ExternalAuthController.cs b/ahk-backend/Ahk.Web.Server/Auth/ExternalAuthController.cs new file mode 100644 index 00000000..7a211acf --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Auth/ExternalAuthController.cs @@ -0,0 +1,85 @@ +using System.Security.Claims; +using Ahk.Web.Data.Entities; +using Ahk.Web.Server.Configuration; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; + +namespace Ahk.Web.Server.Auth; + +/// +/// Generic OIDC external login. The SPA navigates the browser to challenge, which redirects to the OIDC +/// provider; the provider posts back to the OIDC handler (SignInScheme = external cookie) which returns to +/// callback. There the external identity is linked/created and the Identity application cookie is issued, +/// then the browser is redirected back into the SPA. +/// +[ApiController] +[Route("api/auth/external")] +public sealed class ExternalAuthController : ControllerBase +{ + public const string Scheme = "oidc"; + + private readonly SignInManager signInManager; + private readonly UserManager userManager; + private readonly OidcOptions oidcOptions; + + public ExternalAuthController(SignInManager signInManager, UserManager userManager, IOptions oidcOptions) + { + this.signInManager = signInManager; + this.userManager = userManager; + this.oidcOptions = oidcOptions.Value; + } + + [HttpGet("challenge")] + public IActionResult Challenge([FromQuery] string? returnUrl) + { + if (!oidcOptions.IsEnabled) + return BadRequest(new { error = "OIDC is not configured." }); + + var redirectUrl = Url.Action(nameof(Callback), values: new { returnUrl }); + var properties = signInManager.ConfigureExternalAuthenticationProperties(Scheme, redirectUrl); + return Challenge(properties, Scheme); + } + + [HttpGet("callback")] + public async Task Callback([FromQuery] string? returnUrl) + { + var info = await signInManager.GetExternalLoginInfoAsync(); + if (info is null) + return Redirect(SafeReturnUrl(returnUrl, error: "external_login_failed")); + + var signInResult = await signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: true, bypassTwoFactor: true); + if (!signInResult.Succeeded) + { + // First time this external identity is seen: provision a local user and link the login. + var email = info.Principal.FindFirstValue(ClaimTypes.Email); + var name = info.Principal.FindFirstValue(ClaimTypes.Name) ?? email ?? info.ProviderKey; + + var user = (email is not null ? await userManager.FindByEmailAsync(email) : null) + ?? new ApplicationUser { UserName = email ?? $"{info.LoginProvider}:{info.ProviderKey}", Email = email, DisplayName = name, EmailConfirmed = true }; + + if (user.Id.Length == 0 || await userManager.FindByIdAsync(user.Id) is null) + { + var created = await userManager.CreateAsync(user); + if (!created.Succeeded) + return Redirect(SafeReturnUrl(returnUrl, error: "user_creation_failed")); + } + + await userManager.AddLoginAsync(user, info); + await signInManager.SignInAsync(user, isPersistent: true); + } + + return Redirect(SafeReturnUrl(returnUrl)); + } + + // Only allow relative return paths to avoid open-redirects; default to the SPA root. + private string SafeReturnUrl(string? returnUrl, string? error = null) + { + var target = Url.IsLocalUrl(returnUrl) ? returnUrl! : "/"; + if (error is null) + return target; + + return target + (target.Contains('?', StringComparison.Ordinal) ? "&" : "?") + "error=" + Uri.EscapeDataString(error); + } +} diff --git a/ahk-backend/Ahk.Web.Server/Configuration/OidcOptions.cs b/ahk-backend/Ahk.Web.Server/Configuration/OidcOptions.cs new file mode 100644 index 00000000..43311f3d --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Configuration/OidcOptions.cs @@ -0,0 +1,22 @@ +namespace Ahk.Web.Server.Configuration; + +/// +/// Generic OpenID Connect provider settings (bound from configuration section Authentication:Oidc). +/// When is empty the external login handler is not registered and OIDC is disabled, +/// so the app runs with local username/password only. +/// +public sealed class OidcOptions +{ + public const string SectionName = "Authentication:Oidc"; + + public string? Authority { get; set; } + + public string? ClientId { get; set; } + + public string? ClientSecret { get; set; } + + /// Scopes to request in addition to openid/profile. Defaults to email. + public string[] Scopes { get; set; } = new[] { "email" }; + + public bool IsEnabled => !string.IsNullOrWhiteSpace(Authority) && !string.IsNullOrWhiteSpace(ClientId); +} diff --git a/ahk-backend/Ahk.Web.Server/CourseContext/CourseMembershipAuthorizationHandler.cs b/ahk-backend/Ahk.Web.Server/CourseContext/CourseMembershipAuthorizationHandler.cs new file mode 100644 index 00000000..f98480a2 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/CourseContext/CourseMembershipAuthorizationHandler.cs @@ -0,0 +1,50 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; + +namespace Ahk.Web.Server.CourseContext; + +/// +/// Grants the CourseMember policy when the authenticated user has a in the +/// resolved current course. Site admins () are allowed into any course. +/// +public sealed class CourseMembershipAuthorizationHandler : AuthorizationHandler +{ + private readonly ICurrentCourseProvider currentCourse; + private readonly ApplicationDbContext db; + private readonly UserManager userManager; + + public CourseMembershipAuthorizationHandler(ICurrentCourseProvider currentCourse, ApplicationDbContext db, UserManager userManager) + { + this.currentCourse = currentCourse; + this.db = db; + this.userManager = userManager; + } + + protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, CourseMembershipRequirement requirement) + { + if (currentCourse.CurrentCourseId is not Guid courseId) + return; + + if (context.User.Identity?.IsAuthenticated != true) + return; + + if (context.User.IsInRole(Roles.Admin)) + { + context.Succeed(requirement); + return; + } + + var userId = userManager.GetUserId(context.User); + if (userId is null) + return; + + var isMember = await db.CourseMemberships.AsNoTracking() + .AnyAsync(m => m.CourseId == courseId && m.UserId == userId); + + if (isMember) + context.Succeed(requirement); + } +} diff --git a/ahk-backend/Ahk.Web.Server/CourseContext/CourseMembershipRequirement.cs b/ahk-backend/Ahk.Web.Server/CourseContext/CourseMembershipRequirement.cs new file mode 100644 index 00000000..36235de7 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/CourseContext/CourseMembershipRequirement.cs @@ -0,0 +1,9 @@ +using Microsoft.AspNetCore.Authorization; + +namespace Ahk.Web.Server.CourseContext; + +/// Requires the current user to be a member of the resolved current course (site admins bypass). +public sealed class CourseMembershipRequirement : IAuthorizationRequirement +{ + public const string PolicyName = "CourseMember"; +} diff --git a/ahk-backend/Ahk.Web.Server/CourseContext/CourseResolutionMiddleware.cs b/ahk-backend/Ahk.Web.Server/CourseContext/CourseResolutionMiddleware.cs new file mode 100644 index 00000000..692a41e1 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/CourseContext/CourseResolutionMiddleware.cs @@ -0,0 +1,42 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Microsoft.EntityFrameworkCore; + +namespace Ahk.Web.Server.CourseContext; + +/// +/// Resolves the {course} route segment (present on /api/{course}/... routes) to a , +/// stores it in HttpContext.Items["Course"], and sets the request's +/// so the DbContext course filter applies. Returns 404 when the slug does not match a course. Routes without a +/// {course} segment (auth, admin, integrations) pass through untouched. +/// +/// Runs after routing (needs route values) and after authentication. Course *membership* is enforced separately +/// by via the CourseMember policy. +/// +public sealed class CourseResolutionMiddleware +{ + public const string CourseRouteKey = "course"; + public const string CourseItemKey = "Course"; + + private readonly RequestDelegate next; + + public CourseResolutionMiddleware(RequestDelegate next) => this.next = next; + + public async Task InvokeAsync(HttpContext context, ApplicationDbContext db, CurrentCourseProvider currentCourse) + { + if (context.GetRouteValue(CourseRouteKey) is string slug && !string.IsNullOrEmpty(slug)) + { + var course = await db.Courses.AsNoTracking().FirstOrDefaultAsync(c => c.Slug == slug); + if (course is null) + { + context.Response.StatusCode = StatusCodes.Status404NotFound; + return; + } + + currentCourse.Set(course.Id); + context.Items[CourseItemKey] = course; + } + + await this.next(context); + } +} diff --git a/ahk-backend/Ahk.Web.Server/CourseContext/CurrentCourseProvider.cs b/ahk-backend/Ahk.Web.Server/CourseContext/CurrentCourseProvider.cs new file mode 100644 index 00000000..030d4f78 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/CourseContext/CurrentCourseProvider.cs @@ -0,0 +1,14 @@ +using Ahk.Web.Data; + +namespace Ahk.Web.Server.CourseContext; + +/// +/// Scoped per request. sets the active course from the {course} route +/// segment; reads it to apply the course query filter. +/// +public sealed class CurrentCourseProvider : ICurrentCourseProvider +{ + public Guid? CurrentCourseId { get; private set; } + + public void Set(Guid courseId) => CurrentCourseId = courseId; +} diff --git a/ahk-backend/Ahk.Web.Server/Courses/CourseProbeController.cs b/ahk-backend/Ahk.Web.Server/Courses/CourseProbeController.cs new file mode 100644 index 00000000..3f7267ec --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Courses/CourseProbeController.cs @@ -0,0 +1,62 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Ahk.Web.Server.CourseContext; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace Ahk.Web.Server.Courses; + +/// +/// Course context (/api/{course}/...). Temporary endpoint that proves course-scoping end-to-end: +/// the CourseMember policy gates access, and reads/writes are automatically confined to the current +/// course by the EF query filter. Removed once real course endpoints land in the port. +/// +[ApiController] +[Route("api/{course}/probe")] +[Authorize(Policy = CourseMembershipRequirement.PolicyName)] +public sealed class CourseProbeController : ControllerBase +{ + private readonly ApplicationDbContext db; + + public CourseProbeController(ApplicationDbContext db) => this.db = db; + + /// Returns notes for the current course only (enforced by the global query filter). + [HttpGet("notes")] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + public async Task>> GetNotes() + { + var notes = await db.CourseNotes + .AsNoTracking() + .OrderByDescending(n => n.CreatedAt) + .Select(n => new CourseNoteDto { Id = n.Id, Text = n.Text, CreatedAt = n.CreatedAt }) + .ToListAsync(); + + return Ok(notes); + } + + [HttpPost("notes")] + [ProducesResponseType(typeof(CourseNoteDto), StatusCodes.Status200OK)] + public async Task> AddNote([FromBody] CreateCourseNoteRequest request, [FromServices] ICurrentCourseProvider currentCourse) + { + var note = new CourseNote { CourseId = currentCourse.CurrentCourseId!.Value, Text = request.Text }; + db.CourseNotes.Add(note); + await db.SaveChangesAsync(); + + return Ok(new CourseNoteDto { Id = note.Id, Text = note.Text, CreatedAt = note.CreatedAt }); + } +} + +public sealed class CourseNoteDto +{ + public Guid Id { get; set; } + + public string Text { get; set; } = string.Empty; + + public DateTimeOffset CreatedAt { get; set; } +} + +public sealed class CreateCourseNoteRequest +{ + public string Text { get; set; } = string.Empty; +} diff --git a/ahk-backend/Ahk.Web.Server/Program.cs b/ahk-backend/Ahk.Web.Server/Program.cs new file mode 100644 index 00000000..77a484e3 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Program.cs @@ -0,0 +1,116 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Ahk.Web.Data.Seed; +using Ahk.Web.Server.Auth; +using Ahk.Web.Server.Configuration; +using Ahk.Web.Server.CourseContext; +using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; + +var builder = WebApplication.CreateBuilder(args); + +// ---- Options ---- +builder.Services.Configure(builder.Configuration.GetSection(OidcOptions.SectionName)); +var oidc = builder.Configuration.GetSection(OidcOptions.SectionName).Get() ?? new OidcOptions(); + +// ---- EF Core + course scoping ---- +builder.Services.AddHttpContextAccessor(); +builder.Services.AddScoped(); +builder.Services.AddScoped(sp => sp.GetRequiredService()); +builder.Services.AddDbContext(options => + options.UseSqlServer(builder.Configuration.GetConnectionString("Default"))); + +// ---- Identity (cookie-based; no MapIdentityApi — see plan) ---- +builder.Services + .AddIdentity(options => + { + options.User.RequireUniqueEmail = false; + options.SignIn.RequireConfirmedAccount = false; + options.Password.RequireNonAlphanumeric = false; + }) + .AddEntityFrameworkStores() + .AddDefaultTokenProviders(); + +// The SPA calls the API; make the cookie handler return 401/403 instead of redirecting to login/denied pages. +builder.Services.ConfigureApplicationCookie(options => +{ + options.Cookie.HttpOnly = true; + options.Cookie.SameSite = SameSiteMode.Lax; + options.Cookie.SecurePolicy = CookieSecurePolicy.Always; + options.Events.OnRedirectToLogin = ctx => + { + ctx.Response.StatusCode = StatusCodes.Status401Unauthorized; + return Task.CompletedTask; + }; + options.Events.OnRedirectToAccessDenied = ctx => + { + ctx.Response.StatusCode = StatusCodes.Status403Forbidden; + return Task.CompletedTask; + }; +}); + +// ---- Generic OIDC external login (registered only when configured) ---- +if (oidc.IsEnabled) +{ + builder.Services.AddAuthentication().AddOpenIdConnect(ExternalAuthController.Scheme, options => + { + options.Authority = oidc.Authority; + options.ClientId = oidc.ClientId; + options.ClientSecret = oidc.ClientSecret; + options.ResponseType = "code"; + options.UsePkce = true; + options.SaveTokens = true; + options.CallbackPath = "/signin-oidc"; + options.SignInScheme = IdentityConstants.ExternalScheme; + options.Scope.Clear(); + options.Scope.Add("openid"); + options.Scope.Add("profile"); + foreach (var scope in oidc.Scopes) + options.Scope.Add(scope); + options.GetClaimsFromUserInfoEndpoint = true; + }); +} + +// ---- Authorization ---- +builder.Services.AddScoped(); +builder.Services.AddAuthorization(options => +{ + options.AddPolicy(CourseMembershipRequirement.PolicyName, policy => + policy.Requirements.Add(new CourseMembershipRequirement())); +}); + +// ---- MVC + OpenAPI (NSwag document consumed by the Angular code generator) ---- +builder.Services.AddControllers(); +builder.Services.AddOpenApiDocument(settings => +{ + settings.DocumentName = "v1"; + settings.Title = "AHK API"; + settings.Version = "v1"; +}); + +var app = builder.Build(); + +if (app.Environment.IsDevelopment()) +{ + app.UseOpenApi(); // /swagger/v1/swagger.json + app.UseSwaggerUi(); // /swagger + await DevDataSeeder.SeedAsync(app.Services); +} + +app.UseHttpsRedirection(); + +app.UseRouting(); +app.UseAuthentication(); +app.UseMiddleware(); +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); + +// Exposed for WebApplicationFactory-based integration tests. +public partial class Program +{ +} diff --git a/ahk-backend/Ahk.Web.Server/Properties/launchSettings.json b/ahk-backend/Ahk.Web.Server/Properties/launchSettings.json new file mode 100644 index 00000000..e7d3eac9 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Properties/launchSettings.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7443;http://localhost:5234", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "http://localhost:5234", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/ahk-backend/Ahk.Web.Server/appsettings.Development.json b/ahk-backend/Ahk.Web.Server/appsettings.Development.json new file mode 100644 index 00000000..da03147c --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/appsettings.Development.json @@ -0,0 +1,19 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "ConnectionStrings": { + "Default": "Server=(localdb)\\MSSQLLocalDB;Database=AhkWeb;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=True" + }, + "Authentication": { + "Oidc": { + "Authority": "", + "ClientId": "", + "ClientSecret": "", + "Scopes": [ "email" ] + } + } +} diff --git a/ahk-backend/Ahk.Web.Server/appsettings.json b/ahk-backend/Ahk.Web.Server/appsettings.json new file mode 100644 index 00000000..7fa5cc40 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/appsettings.json @@ -0,0 +1,20 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "ConnectionStrings": { + "Default": "" + }, + "Authentication": { + "Oidc": { + "Authority": "", + "ClientId": "", + "ClientSecret": "", + "Scopes": [ "email" ] + } + } +} diff --git a/ahk-backend/Ahk.Web.slnx b/ahk-backend/Ahk.Web.slnx new file mode 100644 index 00000000..27d07430 --- /dev/null +++ b/ahk-backend/Ahk.Web.slnx @@ -0,0 +1,5 @@ + + + + + diff --git a/ahk-backend/README.md b/ahk-backend/README.md new file mode 100644 index 00000000..74892678 --- /dev/null +++ b/ahk-backend/README.md @@ -0,0 +1,54 @@ +# AHK Backend + +Centralized ASP.NET Core (.NET 10) Web API for the AHK portal at `ahk.aut.bme.hu`. Replaces the +per-course Azure Functions deployments with a single site whose domain data is assigned to +**Courses**. Provides ASP.NET Identity authentication (local username/password + generic OIDC, +cookie-based) and course-scoped, membership-authorized endpoints. + +> Skeleton milestone: auth + course-scoping plumbing + OpenAPI. The github-monitor / +> grade-management functionality is ported in a later milestone. See the architecture plan for the +> full design. + +## Projects + +- **Ahk.Web.Server** — Web API host: `Program.cs` wiring, `Auth/` (local + OIDC controllers), + `Admin/` (host-context course management), `Courses/` (course-context endpoints), + `CourseContext/` (course resolution middleware + membership authorization). +- **Ahk.Web.Data** — EF Core `ApplicationDbContext` (Identity + `Course`/`CourseMembership` + + `ICourseScoped` global query filter), migrations, and the dev data seeder. +- **Ahk.Web.Server.Tests** — xUnit tests (course-scoping unit tests + API smoke tests via + `WebApplicationFactory`). + +## Run + +```bash +# 1. Create/upgrade the database (LocalDB by default; see appsettings.Development.json) +dotnet ef database update --project Ahk.Web.Data --startup-project Ahk.Web.Data + +# 2. Run the API over HTTPS (Swagger UI at /swagger, OpenAPI at /swagger/v1/swagger.json) +dotnet run --project Ahk.Web.Server --launch-profile https # https://localhost:7443 + +# Tests +dotnet test +``` + +Dev data seeder (Development env only) creates: + +- site admin — `admin` / `Admin123!` +- instructor (member of `viaubc01` only) — `instructor` / `Instructor123!` +- sample courses `viaubc01`, `viaubb01` + +## Configuration (`AHK`-style keys under `Authentication`/`ConnectionStrings`) + +- `ConnectionStrings:Default` — MSSQL connection string. +- `Authentication:Oidc:{Authority,ClientId,ClientSecret,Scopes}` — generic OIDC provider. When + `Authority`/`ClientId` are empty, OIDC is disabled and the app runs with local login only. + +## Auth model + +- Cookie-based ASP.NET Identity (the API returns 401/403 rather than redirecting). We intentionally + do **not** use `MapIdentityApi` — see the architecture plan for the rationale (no OIDC support, + bearer-token focus, fixed shapes). +- Course context: `/api/{course}/...` routes are resolved to a `Course` and gated by the + `CourseMember` policy. Host/admin routes live under `/api/admin/...`. Machine-to-machine webhook + endpoints (added in the port) resolve their course from the payload/token, not the path segment. diff --git a/ahk-frontend/.editorconfig b/ahk-frontend/.editorconfig new file mode 100644 index 00000000..f166060d --- /dev/null +++ b/ahk-frontend/.editorconfig @@ -0,0 +1,17 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single +ij_typescript_use_double_quotes = false + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/ahk-frontend/.gitignore b/ahk-frontend/.gitignore new file mode 100644 index 00000000..854acd5f --- /dev/null +++ b/ahk-frontend/.gitignore @@ -0,0 +1,44 @@ +# See https://docs.github.com/get-started/getting-started-with-git/ignoring-files for more about ignoring files. + +# Compiled output +/dist +/tmp +/out-tsc +/bazel-out + +# Node +/node_modules +npm-debug.log +yarn-error.log + +# IDEs and editors +.idea/ +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# Visual Studio Code +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/mcp.json +.history/* + +# Miscellaneous +/.angular/cache +.sass-cache/ +/connect.lock +/coverage +/libpeerconnection.log +testem.log +/typings +__screenshots__/ + +# System files +.DS_Store +Thumbs.db diff --git a/ahk-frontend/.prettierrc b/ahk-frontend/.prettierrc new file mode 100644 index 00000000..d6c16d7e --- /dev/null +++ b/ahk-frontend/.prettierrc @@ -0,0 +1,12 @@ +{ + "printWidth": 100, + "singleQuote": true, + "overrides": [ + { + "files": "*.html", + "options": { + "parser": "angular" + } + } + ] +} diff --git a/ahk-frontend/.vscode/extensions.json b/ahk-frontend/.vscode/extensions.json new file mode 100644 index 00000000..77b37457 --- /dev/null +++ b/ahk-frontend/.vscode/extensions.json @@ -0,0 +1,4 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846 + "recommendations": ["angular.ng-template"] +} diff --git a/ahk-frontend/.vscode/launch.json b/ahk-frontend/.vscode/launch.json new file mode 100644 index 00000000..925af837 --- /dev/null +++ b/ahk-frontend/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "ng serve", + "type": "chrome", + "request": "launch", + "preLaunchTask": "npm: start", + "url": "http://localhost:4200/" + }, + { + "name": "ng test", + "type": "chrome", + "request": "launch", + "preLaunchTask": "npm: test", + "url": "http://localhost:9876/debug.html" + } + ] +} diff --git a/ahk-frontend/.vscode/mcp.json b/ahk-frontend/.vscode/mcp.json new file mode 100644 index 00000000..956af8c6 --- /dev/null +++ b/ahk-frontend/.vscode/mcp.json @@ -0,0 +1,9 @@ +{ + // For more information, visit: https://angular.dev/ai/mcp + "servers": { + "angular-cli": { + "command": "npx", + "args": ["-y", "@angular/cli", "mcp"] + } + } +} diff --git a/ahk-frontend/.vscode/tasks.json b/ahk-frontend/.vscode/tasks.json new file mode 100644 index 00000000..244306f9 --- /dev/null +++ b/ahk-frontend/.vscode/tasks.json @@ -0,0 +1,42 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558 + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "start", + "isBackground": true, + "problemMatcher": { + "owner": "typescript", + "pattern": "$tsc", + "background": { + "activeOnStart": true, + "beginsPattern": { + "regexp": "Changes detected" + }, + "endsPattern": { + "regexp": "bundle generation (complete|failed)" + } + } + } + }, + { + "type": "npm", + "script": "test", + "isBackground": true, + "problemMatcher": { + "owner": "typescript", + "pattern": "$tsc", + "background": { + "activeOnStart": true, + "beginsPattern": { + "regexp": "Changes detected" + }, + "endsPattern": { + "regexp": "bundle generation (complete|failed)" + } + } + } + } + ] +} diff --git a/ahk-frontend/README.md b/ahk-frontend/README.md new file mode 100644 index 00000000..e54bb3f6 --- /dev/null +++ b/ahk-frontend/README.md @@ -0,0 +1,51 @@ +# AHK Frontend + +Angular 21 SPA (teacher portal) for `ahk.aut.bme.hu`, talking to **ahk-backend**. Standalone +components + signals. Cookie-based auth; in dev the SPA and API are made same-origin by a proxy so +**no CORS** is needed. + +> Skeleton milestone: login (local + OIDC), a host/admin course-management screen, and a +> course-scoped dashboard that exercises course isolation. Real dashboards land in the port. + +## Structure + +- `src/app/api/` — **NSwag-generated** TypeScript clients + DTOs (do not edit by hand; run + `npm run generate-api`). +- `src/app/core/auth/` — `AuthService` (session signals), functional guards, HTTP interceptor. +- `src/app/core/course/` — active-course context + course membership guard. +- `src/app/layout/shell/` — authenticated app frame with course switcher. +- `src/app/features/` — `login/`, `admin/courses/`, `course/dashboard/`. + +## Run (dev, HTTPS) + +```bash +npm install +npm start # ng serve --ssl on https://localhost:4200, proxying /api → https://localhost:7443 +``` + +Start **ahk-backend** first (https://localhost:7443). Log in with a seeded account, e.g. +`admin` / `Admin123!` or `instructor` / `Instructor123!`. + +## Regenerate the API client + +```bash +# ahk-backend must be running (its OpenAPI doc is the source) +npm run generate-api # NSwag reads https://localhost:7443/swagger/v1/swagger.json → src/app/api/api-client.ts +``` + +Note: `nswag.json` uses `"runtime": "Net100"` to match the installed .NET 10 SDK. + +## Build / test + +```bash +npm run build +npm test +``` + +## Dev proxy & auth notes + +- `proxy.conf.js` forwards `/api/*` to the backend over HTTPS (`secure: false` for the self-signed + dev cert). `API_BASE_URL` is provided as `''` so the generated clients issue **relative** requests + (same-origin → cookie flows, no CORS). +- OIDC login is a full-page navigation to `/api/auth/external/challenge` (proxied to the backend), + which runs the standard redirect flow and issues the Identity cookie. diff --git a/ahk-frontend/angular.json b/ahk-frontend/angular.json new file mode 100644 index 00000000..af5f676a --- /dev/null +++ b/ahk-frontend/angular.json @@ -0,0 +1,83 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "cli": { + "packageManager": "npm" + }, + "newProjectRoot": "projects", + "projects": { + "ahk-frontend": { + "projectType": "application", + "schematics": { + "@schematics/angular:component": { + "style": "scss" + } + }, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular/build:application", + "options": { + "browser": "src/main.ts", + "tsConfig": "tsconfig.app.json", + "inlineStyleLanguage": "scss", + "assets": [ + { + "glob": "**/*", + "input": "public" + } + ], + "styles": [ + "src/styles.scss" + ] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kB", + "maximumError": "1MB" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kB", + "maximumError": "8kB" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular/build:dev-server", + "options": { + "ssl": true, + "port": 4200, + "proxyConfig": "proxy.conf.js" + }, + "configurations": { + "production": { + "buildTarget": "ahk-frontend:build:production" + }, + "development": { + "buildTarget": "ahk-frontend:build:development" + } + }, + "defaultConfiguration": "development" + }, + "test": { + "builder": "@angular/build:unit-test" + } + } + } + } +} diff --git a/ahk-frontend/nswag.json b/ahk-frontend/nswag.json new file mode 100644 index 00000000..5bd8f426 --- /dev/null +++ b/ahk-frontend/nswag.json @@ -0,0 +1,33 @@ +{ + "runtime": "Net100", + "defaultVariables": null, + "documentGenerator": { + "fromDocument": { + "url": "https://localhost:7443/swagger/v1/swagger.json" + } + }, + "codeGenerators": { + "openApiToTypeScriptClient": { + "className": "{controller}Client", + "moduleName": "", + "namespace": "", + "typeScriptVersion": 5.2, + "template": "Angular", + "httpClass": "HttpClient", + "withCredentials": true, + "useSingletonProvider": true, + "injectionTokenType": "InjectionToken", + "rxJsVersion": 7.0, + "dateTimeType": "Date", + "generateClientClasses": true, + "generateClientInterfaces": true, + "generateDtoTypes": true, + "operationGenerationMode": "MultipleClientsFromFirstTagAndOperationName", + "markOptionalProperties": true, + "generateOptionalParameters": true, + "typeStyle": "Interface", + "enumStyle": "StringLiteral", + "output": "src/app/api/api-client.ts" + } + } +} diff --git a/ahk-frontend/package-lock.json b/ahk-frontend/package-lock.json new file mode 100644 index 00000000..089a52e0 --- /dev/null +++ b/ahk-frontend/package-lock.json @@ -0,0 +1,8586 @@ +{ + "name": "ahk-frontend", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "ahk-frontend", + "version": "0.0.0", + "dependencies": { + "@angular/common": "^21.2.0", + "@angular/compiler": "^21.2.0", + "@angular/core": "^21.2.0", + "@angular/forms": "^21.2.0", + "@angular/platform-browser": "^21.2.0", + "@angular/router": "^21.2.0", + "rxjs": "~7.8.0", + "tslib": "^2.3.0" + }, + "devDependencies": { + "@angular/build": "^21.2.8", + "@angular/cli": "^21.2.8", + "@angular/compiler-cli": "^21.2.0", + "jsdom": "^28.0.0", + "nswag": "^14.7.1", + "prettier": "^3.8.1", + "typescript": "~5.9.2", + "vitest": "^4.0.8" + } + }, + "node_modules/@acemir/cssom": { + "version": "0.9.31", + "resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.31.tgz", + "integrity": "sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@algolia/abtesting": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.14.1.tgz", + "integrity": "sha512-Dkj0BgPiLAaim9sbQ97UKDFHJE/880wgStAM18U++NaJ/2Cws34J5731ovJifr6E3Pv4T2CqvMXf8qLCC417Ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.48.1", + "@algolia/requester-browser-xhr": "5.48.1", + "@algolia/requester-fetch": "5.48.1", + "@algolia/requester-node-http": "5.48.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-abtesting": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.48.1.tgz", + "integrity": "sha512-LV5qCJdj+/m9I+Aj91o+glYszrzd7CX6NgKaYdTOj4+tUYfbS62pwYgUfZprYNayhkQpVFcrW8x8ZlIHpS23Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.48.1", + "@algolia/requester-browser-xhr": "5.48.1", + "@algolia/requester-fetch": "5.48.1", + "@algolia/requester-node-http": "5.48.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.48.1.tgz", + "integrity": "sha512-/AVoMqHhPm14CcHq7mwB+bUJbfCv+jrxlNvRjXAuO+TQa+V37N8k1b0ijaRBPdmSjULMd8KtJbQyUyabXOu6Kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.48.1", + "@algolia/requester-browser-xhr": "5.48.1", + "@algolia/requester-fetch": "5.48.1", + "@algolia/requester-node-http": "5.48.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-common": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.48.1.tgz", + "integrity": "sha512-VXO+qu2Ep6ota28ktvBm3sG53wUHS2n7bgLWmce5jTskdlCD0/JrV4tnBm1l7qpla1CeoQb8D7ShFhad+UoSOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-insights": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.48.1.tgz", + "integrity": "sha512-zl+Qyb0nLg+Y5YvKp1Ij+u9OaPaKg2/EPzTwKNiVyOHnQJlFxmXyUZL1EInczAZsEY8hVpPCLtNfhMhfxluXKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.48.1", + "@algolia/requester-browser-xhr": "5.48.1", + "@algolia/requester-fetch": "5.48.1", + "@algolia/requester-node-http": "5.48.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.48.1.tgz", + "integrity": "sha512-r89Qf9Oo9mKWQXumRu/1LtvVJAmEDpn8mHZMc485pRfQUMAwSSrsnaw1tQ3sszqzEgAr1c7rw6fjBI+zrAXTOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.48.1", + "@algolia/requester-browser-xhr": "5.48.1", + "@algolia/requester-fetch": "5.48.1", + "@algolia/requester-node-http": "5.48.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-query-suggestions": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.48.1.tgz", + "integrity": "sha512-TPKNPKfghKG/bMSc7mQYD9HxHRUkBZA4q1PEmHgICaSeHQscGqL4wBrKkhfPlDV1uYBKW02pbFMUhsOt7p4ZpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.48.1", + "@algolia/requester-browser-xhr": "5.48.1", + "@algolia/requester-fetch": "5.48.1", + "@algolia/requester-node-http": "5.48.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-search": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.48.1.tgz", + "integrity": "sha512-4Fu7dnzQyQmMFknYwTiN/HxPbH4DyxvQ1m+IxpPp5oslOgz8m6PG5qhiGbqJzH4HiT1I58ecDiCAC716UyVA8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.48.1", + "@algolia/requester-browser-xhr": "5.48.1", + "@algolia/requester-fetch": "5.48.1", + "@algolia/requester-node-http": "5.48.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/ingestion": { + "version": "1.48.1", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.48.1.tgz", + "integrity": "sha512-/RFq3TqtXDUUawwic/A9xylA2P3LDMO8dNhphHAUOU51b1ZLHrmZ6YYJm3df1APz7xLY1aht6okCQf+/vmrV9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.48.1", + "@algolia/requester-browser-xhr": "5.48.1", + "@algolia/requester-fetch": "5.48.1", + "@algolia/requester-node-http": "5.48.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/monitoring": { + "version": "1.48.1", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.48.1.tgz", + "integrity": "sha512-Of0jTeAZRyRhC7XzDSjJef0aBkgRcvRAaw0ooYRlOw57APii7lZdq+layuNdeL72BRq1snaJhoMMwkmLIpJScw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.48.1", + "@algolia/requester-browser-xhr": "5.48.1", + "@algolia/requester-fetch": "5.48.1", + "@algolia/requester-node-http": "5.48.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/recommend": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.48.1.tgz", + "integrity": "sha512-bE7JcpFXzxF5zHwj/vkl2eiCBvyR1zQ7aoUdO+GDXxGp0DGw7nI0p8Xj6u8VmRQ+RDuPcICFQcCwRIJT5tDJFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.48.1", + "@algolia/requester-browser-xhr": "5.48.1", + "@algolia/requester-fetch": "5.48.1", + "@algolia/requester-node-http": "5.48.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.48.1.tgz", + "integrity": "sha512-MK3wZ2koLDnvH/AmqIF1EKbJlhRS5j74OZGkLpxI4rYvNi9Jn/C7vb5DytBnQ4KUWts7QsmbdwHkxY5txQHXVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.48.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-fetch": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.48.1.tgz", + "integrity": "sha512-2oDT43Y5HWRSIQMPQI4tA/W+TN/N2tjggZCUsqQV440kxzzoPGsvv9QP1GhQ4CoDa+yn6ygUsGp6Dr+a9sPPSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.48.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-node-http": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.48.1.tgz", + "integrity": "sha512-xcaCqbhupVWhuBP1nwbk1XNvwrGljozutEiLx06mvqDf3o8cHyEgQSHS4fKJM+UAggaWVnnFW+Nne5aQ8SUJXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.48.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@angular-devkit/architect": { + "version": "0.2102.19", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2102.19.tgz", + "integrity": "sha512-cj4tzUMiloLTg5rNf17E8MsvIxCWYoBiBsaj7ns6dgXqT9XCeG+J0TA2t1M+N9uuqfeLd22U/rYoCkADmcircQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "21.2.19", + "rxjs": "7.8.2" + }, + "bin": { + "architect": "bin/cli.js" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/core": { + "version": "21.2.19", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.2.19.tgz", + "integrity": "sha512-dtpJMQBz5nhkcIogPmXP/aT2Ak8m/wLRPOSTI/g4vSJSuGiI53PgtWq4/wfQga6E6wdM2XWsblAE89d8w5heQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "8.18.0", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.4", + "rxjs": "7.8.2", + "source-map": "0.7.6" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^5.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics": { + "version": "21.2.19", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-21.2.19.tgz", + "integrity": "sha512-AG3Fzh9wJCmKBfxUQOUWaEHMj5Gq2O+Msf1z52aDSxbVhs5/iSQcXGPv/DLdAXu7d4xmQhLouNe9Glaq2omDyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "21.2.19", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.21", + "ora": "9.3.0", + "rxjs": "7.8.2" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/build": { + "version": "21.2.19", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-21.2.19.tgz", + "integrity": "sha512-emy9mqrTXAwhZzcvx8MaHyz+cUR06PVGxnqy91+bpDxPP9S5x67sPoOkY9y/ETFFhRpB5ULlUxyq0eN/pi6QOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.2102.19", + "@babel/core": "7.29.7", + "@babel/helper-annotate-as-pure": "7.27.3", + "@babel/helper-split-export-declaration": "7.24.7", + "@inquirer/confirm": "5.1.21", + "@vitejs/plugin-basic-ssl": "2.1.4", + "beasties": "0.4.1", + "browserslist": "^4.26.0", + "esbuild": "0.28.1", + "https-proxy-agent": "7.0.6", + "istanbul-lib-instrument": "6.0.3", + "jsonc-parser": "3.3.1", + "listr2": "9.0.5", + "magic-string": "0.30.21", + "mrmime": "2.0.1", + "parse5-html-rewriting-stream": "8.0.0", + "picomatch": "4.0.4", + "piscina": "5.2.0", + "rolldown": "1.0.0-rc.4", + "sass": "1.97.3", + "semver": "7.7.4", + "source-map-support": "0.5.21", + "tinyglobby": "0.2.15", + "undici": "7.28.0", + "vite": "7.3.6", + "watchpack": "2.5.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "lmdb": "3.5.1" + }, + "peerDependencies": { + "@angular/compiler": "^21.0.0", + "@angular/compiler-cli": "^21.0.0", + "@angular/core": "^21.0.0", + "@angular/localize": "^21.0.0", + "@angular/platform-browser": "^21.0.0", + "@angular/platform-server": "^21.0.0", + "@angular/service-worker": "^21.0.0", + "@angular/ssr": "^21.2.19", + "karma": "^6.4.0", + "less": "^4.2.0", + "ng-packagr": "^21.0.0", + "postcss": "^8.4.0", + "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0", + "tslib": "^2.3.0", + "typescript": ">=5.9 <6.0", + "vitest": "^4.0.8" + }, + "peerDependenciesMeta": { + "@angular/core": { + "optional": true + }, + "@angular/localize": { + "optional": true + }, + "@angular/platform-browser": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "karma": { + "optional": true + }, + "less": { + "optional": true + }, + "ng-packagr": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tailwindcss": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, + "node_modules/@angular/cli": { + "version": "21.2.19", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-21.2.19.tgz", + "integrity": "sha512-i78NzvoNonAY17QgzSmqrYnXHmEfraLv4wZ/o/m3efxuz61ZJ+5X/PsCeAhbwBvQfRrPRQaJV2tK9vGjHa+U6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/architect": "0.2102.19", + "@angular-devkit/core": "21.2.19", + "@angular-devkit/schematics": "21.2.19", + "@inquirer/prompts": "7.10.1", + "@listr2/prompt-adapter-inquirer": "3.0.5", + "@modelcontextprotocol/sdk": "1.26.0", + "@schematics/angular": "21.2.19", + "@yarnpkg/lockfile": "1.1.0", + "algoliasearch": "5.48.1", + "ini": "6.0.0", + "jsonc-parser": "3.3.1", + "listr2": "9.0.5", + "npm-package-arg": "13.0.2", + "pacote": "21.5.1", + "parse5-html-rewriting-stream": "8.0.0", + "semver": "7.7.4", + "yargs": "18.0.0", + "zod": "4.3.6" + }, + "bin": { + "ng": "bin/ng.js" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/common": { + "version": "21.2.18", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-21.2.18.tgz", + "integrity": "sha512-gZugZ8gX/KkACIZ3/ekoImLu5z8a0Iu9O5b84kh8e+++VUjmkmd19IygBsq/8/fF3vKf0UcIKcx3P6A/gb2DJw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/core": "21.2.18", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/compiler": { + "version": "21.2.18", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-21.2.18.tgz", + "integrity": "sha512-ccnDuKLuzIa0ayijR+alarsHNWIksuGV/lxGTZ0t6/0+B6J/RXupz6M2IO6ZHHEcg8r7pcrLCUBTyp3FoiRJrg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@angular/compiler-cli": { + "version": "21.2.18", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-21.2.18.tgz", + "integrity": "sha512-L5zbIp7YfTTB4I4xT33FgEBanzhppNejzZX0HJOEqKDyDL2jXq+flt83lE0XVuRJ6/zrG+UKj0B+y/CK6Ro7Wg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "7.29.7", + "@jridgewell/sourcemap-codec": "^1.4.14", + "chokidar": "^5.0.0", + "convert-source-map": "^1.5.1", + "reflect-metadata": "^0.2.0", + "semver": "^7.0.0", + "tslib": "^2.3.0", + "yargs": "^18.0.0" + }, + "bin": { + "ng-xi18n": "bundles/src/bin/ng_xi18n.js", + "ngc": "bundles/src/bin/ngc.js" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/compiler": "21.2.18", + "typescript": ">=5.9 <6.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@angular/core": { + "version": "21.2.18", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-21.2.18.tgz", + "integrity": "sha512-AG4bb6GU0+qp+vVBjc/IhSPjgcRX8QsCb8jzN8dDyhnjsyuuG/LlIiU0l6n65BI9SGKE9m6TfsJ1ObkkAiE5KQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/compiler": "21.2.18", + "rxjs": "^6.5.3 || ^7.4.0", + "zone.js": "~0.15.0 || ~0.16.0" + }, + "peerDependenciesMeta": { + "@angular/compiler": { + "optional": true + }, + "zone.js": { + "optional": true + } + } + }, + "node_modules/@angular/forms": { + "version": "21.2.18", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-21.2.18.tgz", + "integrity": "sha512-TrRuiNjIzrrNtQgpJVH5gultQrvBlawa+tTzIpxBfIqLpkHrTPZLtYu118EUk6jhWzgRhKYUorInjJe+sSxC+w==", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/common": "21.2.18", + "@angular/core": "21.2.18", + "@angular/platform-browser": "21.2.18", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/platform-browser": { + "version": "21.2.18", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-21.2.18.tgz", + "integrity": "sha512-zltF+3HrlgtZbYg8U98LhG0dyGm1aHT3Px8//9wjqi/TUY8UlHsYKByL197QtVWDBjf/dekzXdz5c+iyVtanLQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/animations": "21.2.18", + "@angular/common": "21.2.18", + "@angular/core": "21.2.18" + }, + "peerDependenciesMeta": { + "@angular/animations": { + "optional": true + } + } + }, + "node_modules/@angular/router": { + "version": "21.2.18", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-21.2.18.tgz", + "integrity": "sha512-Xix19uG1YthC8IslhWKSfPdhscVWREBGVJZW2OnRmLef8F7DvhF49S6vOywaBo+Uahe0egkmgWDNpEwxAzsgLw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/common": "21.2.18", + "@angular/core": "21.2.18", + "@angular/platform-browser": "21.2.18", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@asamuzakjp/css-color": { + "version": "5.1.11", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.1.11.tgz", + "integrity": "sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/generational-cache": "^1.0.1", + "@csstools/css-calc": "^3.2.0", + "@csstools/css-color-parser": "^4.1.0", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.8.1.tgz", + "integrity": "sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.1.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.2.6" + } + }, + "node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@asamuzakjp/generational-cache": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/generational-cache/-/generational-cache-1.0.1.tgz", + "integrity": "sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", + "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bramus/specificity": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz", + "integrity": "sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "^3.0.0" + }, + "bin": { + "specificity": "bin/cli.js" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.1.0.tgz", + "integrity": "sha512-064IFJdjTfUqnjpCVpMOdbr8FLQBhinbZj6yRv2An2E41O/pLEXqfFRWqGq/SxlE5PEUYTlvWsG2r8MswAVvkg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@csstools/css-calc": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.2.1.tgz", + "integrity": "sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.1.9.tgz", + "integrity": "sha512-paQcIaOO53Rk5+YrBaBjm/SgrV4INImjo2BT1DtQRYr+XeTRbeAYlS+jxXp9drqvKmtFnWRJKIalDLhZZDu42A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^6.1.0", + "@csstools/css-calc": "^3.2.1" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", + "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.6.tgz", + "integrity": "sha512-TcJCWFbXLPpJYq6z7bfOyjWYJDiDg2/I4gyUC9pqPNqHFRIey0EB0q0L5cSnQDfWJg8Jd6VadakxdIez/3zkqQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "peerDependencies": { + "css-tree": "^3.2.1" + }, + "peerDependenciesMeta": { + "css-tree": { + "optional": true + } + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", + "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.2.tgz", + "integrity": "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.2.tgz", + "integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@exodus/bytes": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.1.tgz", + "integrity": "sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" + }, + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true + } + } + }, + "node_modules/@gar/promise-retry": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@gar/promise-retry/-/promise-retry-1.0.3.tgz", + "integrity": "sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@harperfast/extended-iterable": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@harperfast/extended-iterable/-/extended-iterable-1.0.3.tgz", + "integrity": "sha512-sSAYhQca3rDWtQUHSAPeO7axFIUJOI6hn1gjRC5APVE1a90tuyT8f5WIgRsFhhWA7htNkju2veB9eWL6YHi/Lw==", + "dev": true, + "license": "Apache-2.0", + "optional": true + }, + "node_modules/@hono/node-server": { + "version": "1.19.14", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz", + "integrity": "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" + } + }, + "node_modules/@inquirer/ansi": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.2.tgz", + "integrity": "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.2.tgz", + "integrity": "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/confirm": { + "version": "5.1.21", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.21.tgz", + "integrity": "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core": { + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.2.tgz", + "integrity": "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/editor": { + "version": "4.2.23", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.23.tgz", + "integrity": "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/external-editor": "^1.0.3", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/expand": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.23.tgz", + "integrity": "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/external-editor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", + "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^2.1.1", + "iconv-lite": "^0.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz", + "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.3.1.tgz", + "integrity": "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.23.tgz", + "integrity": "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.23.tgz", + "integrity": "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/prompts": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.10.1.tgz", + "integrity": "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^4.3.2", + "@inquirer/confirm": "^5.1.21", + "@inquirer/editor": "^4.2.23", + "@inquirer/expand": "^4.0.23", + "@inquirer/input": "^4.3.1", + "@inquirer/number": "^3.0.23", + "@inquirer/password": "^4.0.23", + "@inquirer/rawlist": "^4.1.11", + "@inquirer/search": "^3.2.2", + "@inquirer/select": "^4.4.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.11.tgz", + "integrity": "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/search": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.2.tgz", + "integrity": "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/select": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.2.tgz", + "integrity": "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.10.tgz", + "integrity": "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", + "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@listr2/prompt-adapter-inquirer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-3.0.5.tgz", + "integrity": "sha512-WELs+hj6xcilkloBXYf9XXK8tYEnKsgLj01Xl5ONUJpKjmT5hGVUzNUS5tooUxs7pGMrw+jFD/41WpqW4V3LDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/type": "^3.0.8" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@inquirer/prompts": ">= 3 < 8", + "listr2": "9.0.5" + } + }, + "node_modules/@lmdb/lmdb-darwin-arm64": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.5.1.tgz", + "integrity": "sha512-tpfN4kKrrMpQ+If1l8bhmoNkECJi0iOu6AEdrTJvWVC+32sLxTARX5Rsu579mPImRP9YFWfWgeRQ5oav7zApQQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-darwin-x64": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.5.1.tgz", + "integrity": "sha512-+a2tTfc3rmWhLAolFUWRgJtpSuu+Fw/yjn4rF406NMxhfjbMuiOUTDRvRlMFV+DzyjkwnokisskHbCWkS3Ly5w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.5.1.tgz", + "integrity": "sha512-0EgcE6reYr8InjD7V37EgXcYrloqpxVPINy3ig1MwDSbl6LF/vXTYRH9OE1Ti1D8YZnB35ZH9aTcdfSb5lql2A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm64": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.5.1.tgz", + "integrity": "sha512-aoERa5B6ywXdyFeYGQ1gbQpkMkDbEo45qVoXE5QpIRavqjnyPwjOulMkmkypkmsbJ5z4Wi0TBztON8agCTG0Vg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-x64": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.5.1.tgz", + "integrity": "sha512-SqNDY1+vpji7bh0sFH5wlWyFTOzjbDOl0/kB5RLLYDAFyd/uw3n7wyrmas3rYPpAW7z18lMOi1yKlTPv967E3g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-win32-arm64": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-arm64/-/lmdb-win32-arm64-3.5.1.tgz", + "integrity": "sha512-50v0O1Lt37cwrmR9vWZK5hRW0Aw+KEmxJJ75fge/zIYdvNKB/0bSMSVR5Uc2OV9JhosIUyklOmrEvavwNJ8D6w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@lmdb/lmdb-win32-x64": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.5.1.tgz", + "integrity": "sha512-qwosvPyl+zpUlp3gRb7UcJ3H8S28XHCzkv0Y0EgQToXjQP91ZD67EHSCDmaLjtKhe+GVIW5om1KUpzVLA0l6pg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.26.0.tgz", + "integrity": "sha512-Y5RmPncpiDtTXDbLKswIJzTqu2hyBKxTNsgKqKclDbhIgg1wgtf1fRuvxgTnRfcnxtvvgbIEcqUOzZrJ6iSReg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@hono/node-server": "^1.19.9", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.2.1", + "express-rate-limit": "^8.2.1", + "hono": "^4.11.4", + "jose": "^6.1.3", + "json-schema-typed": "^8.0.2", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } + } + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.4.tgz", + "integrity": "sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.4.tgz", + "integrity": "sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.4.tgz", + "integrity": "sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.4.tgz", + "integrity": "sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.4.tgz", + "integrity": "sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.4.tgz", + "integrity": "sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@napi-rs/nice": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.1.1.tgz", + "integrity": "sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/nice-android-arm-eabi": "1.1.1", + "@napi-rs/nice-android-arm64": "1.1.1", + "@napi-rs/nice-darwin-arm64": "1.1.1", + "@napi-rs/nice-darwin-x64": "1.1.1", + "@napi-rs/nice-freebsd-x64": "1.1.1", + "@napi-rs/nice-linux-arm-gnueabihf": "1.1.1", + "@napi-rs/nice-linux-arm64-gnu": "1.1.1", + "@napi-rs/nice-linux-arm64-musl": "1.1.1", + "@napi-rs/nice-linux-ppc64-gnu": "1.1.1", + "@napi-rs/nice-linux-riscv64-gnu": "1.1.1", + "@napi-rs/nice-linux-s390x-gnu": "1.1.1", + "@napi-rs/nice-linux-x64-gnu": "1.1.1", + "@napi-rs/nice-linux-x64-musl": "1.1.1", + "@napi-rs/nice-openharmony-arm64": "1.1.1", + "@napi-rs/nice-win32-arm64-msvc": "1.1.1", + "@napi-rs/nice-win32-ia32-msvc": "1.1.1", + "@napi-rs/nice-win32-x64-msvc": "1.1.1" + } + }, + "node_modules/@napi-rs/nice-android-arm-eabi": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.1.1.tgz", + "integrity": "sha512-kjirL3N6TnRPv5iuHw36wnucNqXAO46dzK9oPb0wj076R5Xm8PfUVA9nAFB5ZNMmfJQJVKACAPd/Z2KYMppthw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-android-arm64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.1.1.tgz", + "integrity": "sha512-blG0i7dXgbInN5urONoUCNf+DUEAavRffrO7fZSeoRMJc5qD+BJeNcpr54msPF6qfDD6kzs9AQJogZvT2KD5nw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-arm64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.1.1.tgz", + "integrity": "sha512-s/E7w45NaLqTGuOjC2p96pct4jRfo61xb9bU1unM/MJ/RFkKlJyJDx7OJI/O0ll/hrfpqKopuAFDV8yo0hfT7A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-x64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.1.1.tgz", + "integrity": "sha512-dGoEBnVpsdcC+oHHmW1LRK5eiyzLwdgNQq3BmZIav+9/5WTZwBYX7r5ZkQC07Nxd3KHOCkgbHSh4wPkH1N1LiQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-freebsd-x64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.1.1.tgz", + "integrity": "sha512-kHv4kEHAylMYmlNwcQcDtXjklYp4FCf0b05E+0h6nDHsZ+F0bDe04U/tXNOqrx5CmIAth4vwfkjjUmp4c4JktQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm-gnueabihf": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.1.1.tgz", + "integrity": "sha512-E1t7K0efyKXZDoZg1LzCOLxgolxV58HCkaEkEvIYQx12ht2pa8hoBo+4OB3qh7e+QiBlp1SRf+voWUZFxyhyqg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.1.1.tgz", + "integrity": "sha512-CIKLA12DTIZlmTaaKhQP88R3Xao+gyJxNWEn04wZwC2wmRapNnxCUZkVwggInMJvtVElA+D4ZzOU5sX4jV+SmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-musl": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.1.1.tgz", + "integrity": "sha512-+2Rzdb3nTIYZ0YJF43qf2twhqOCkiSrHx2Pg6DJaCPYhhaxbLcdlV8hCRMHghQ+EtZQWGNcS2xF4KxBhSGeutg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-ppc64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.1.1.tgz", + "integrity": "sha512-4FS8oc0GeHpwvv4tKciKkw3Y4jKsL7FRhaOeiPei0X9T4Jd619wHNe4xCLmN2EMgZoeGg+Q7GY7BsvwKpL22Tg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-riscv64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.1.1.tgz", + "integrity": "sha512-HU0nw9uD4FO/oGCCk409tCi5IzIZpH2agE6nN4fqpwVlCn5BOq0MS1dXGjXaG17JaAvrlpV5ZeyZwSon10XOXw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-s390x-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.1.1.tgz", + "integrity": "sha512-2YqKJWWl24EwrX0DzCQgPLKQBxYDdBxOHot1KWEq7aY2uYeX+Uvtv4I8xFVVygJDgf6/92h9N3Y43WPx8+PAgQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.1.1.tgz", + "integrity": "sha512-/gaNz3R92t+dcrfCw/96pDopcmec7oCcAQ3l/M+Zxr82KT4DljD37CpgrnXV+pJC263JkW572pdbP3hP+KjcIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-musl": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.1.1.tgz", + "integrity": "sha512-xScCGnyj/oppsNPMnevsBe3pvNaoK7FGvMjT35riz9YdhB2WtTG47ZlbxtOLpjeO9SqqQ2J2igCmz6IJOD5JYw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-openharmony-arm64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-openharmony-arm64/-/nice-openharmony-arm64-1.1.1.tgz", + "integrity": "sha512-6uJPRVwVCLDeoOaNyeiW0gp2kFIM4r7PL2MczdZQHkFi9gVlgm+Vn+V6nTWRcu856mJ2WjYJiumEajfSm7arPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-arm64-msvc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.1.1.tgz", + "integrity": "sha512-uoTb4eAvM5B2aj/z8j+Nv8OttPf2m+HVx3UjA5jcFxASvNhQriyCQF1OB1lHL43ZhW+VwZlgvjmP5qF3+59atA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-ia32-msvc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.1.1.tgz", + "integrity": "sha512-CNQqlQT9MwuCsg1Vd/oKXiuH+TcsSPJmlAFc5frFyX/KkOh0UpBLEj7aoY656d5UKZQMQFP7vJNa1DNUNORvug==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-x64-msvc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.1.1.tgz", + "integrity": "sha512-vB+4G/jBQCAh0jelMTY3+kgFy00Hlx2f2/1zjMoH821IbplbWZOkLiTYXQkygNTzQJTq5cvwBDgn2ppHD+bglQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", + "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@npmcli/agent": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-4.0.2.tgz", + "integrity": "sha512-EUEuWAxnL07Sp5/iC/1X6Xj+XThUvnbei9zfRWZdEXa7lss9RTHMhAHBeg+MZ5To9s/gGaSI+UwZTPdYMvKSeg==", + "dev": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^11.2.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@npmcli/fs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-5.0.0.tgz", + "integrity": "sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==", + "dev": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/git": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-7.0.2.tgz", + "integrity": "sha512-oeolHDjExNAJAnlYP2qzNjMX/Xi9bmu78C9dIGr4xjobrSKbuMYCph8lTzn4vnW3NjIqVmw/f8BCfouqyJXlRg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@gar/promise-retry": "^1.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "ini": "^6.0.0", + "lru-cache": "^11.2.1", + "npm-pick-manifest": "^11.0.1", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "which": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^4.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-4.0.0.tgz", + "integrity": "sha512-yNyAdkBxB72gtZ4GrwXCM0ZUedo9nIbOMKfGjt6Cu6DXf0p8y1PViZAKDC8q8kv/fufx0WTjRBdSlyrvnP7hmA==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^5.0.0", + "npm-normalize-package-bin": "^5.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-5.0.0.tgz", + "integrity": "sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-7.0.5.tgz", + "integrity": "sha512-iVuTlG3ORq2iaVa1IWUxAO/jIp77tUKBhoMjuzYW2kL4MLN1bi/ofqkZ7D7OOwh8coAx1/S2ge0rMdGv8sLSOQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^7.0.0", + "glob": "^13.0.0", + "hosted-git-info": "^9.0.0", + "json-parse-even-better-errors": "^5.0.0", + "proc-log": "^6.0.0", + "semver": "^7.5.3", + "spdx-expression-parse": "^4.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-9.0.1.tgz", + "integrity": "sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "which": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^4.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/redact": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-4.0.0.tgz", + "integrity": "sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-10.0.4.tgz", + "integrity": "sha512-mGUWr1uMnf0le2TwfOZY4SFxZGXGfm4Jtay/nwAa2FLNAKXUoUwaGwBMNH36UHPtinWfTSJ3nqFQr0091CxVGg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "node-gyp": "^12.1.0", + "proc-log": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.113.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.113.0.tgz", + "integrity": "sha512-Tp3XmgxwNQ9pEN9vxgJBAqdRamHibi76iowQ38O2I4PMpcvNRQNVsU2n1x1nv9yh0XoTrGFzf7cZSGxmixxrhA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.6.0.tgz", + "integrity": "sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.3", + "is-glob": "^4.0.3", + "node-addon-api": "^7.0.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.6.0", + "@parcel/watcher-darwin-arm64": "2.6.0", + "@parcel/watcher-darwin-x64": "2.6.0", + "@parcel/watcher-freebsd-x64": "2.6.0", + "@parcel/watcher-linux-arm-glibc": "2.6.0", + "@parcel/watcher-linux-arm-musl": "2.6.0", + "@parcel/watcher-linux-arm64-glibc": "2.6.0", + "@parcel/watcher-linux-arm64-musl": "2.6.0", + "@parcel/watcher-linux-x64-glibc": "2.6.0", + "@parcel/watcher-linux-x64-musl": "2.6.0", + "@parcel/watcher-win32-arm64": "2.6.0", + "@parcel/watcher-win32-x64": "2.6.0" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.6.0.tgz", + "integrity": "sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.6.0.tgz", + "integrity": "sha512-Y3QV0gl7Q1zbfueunkWIERICbEojQFCgpyG7YqOGNFLsckXyI1xu9mAIUpKY9QBYzBtSkN8dBPwd3yiAO9ovMw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.6.0.tgz", + "integrity": "sha512-Ohv6OpzhUfKYD7Beb8kDvG0jbIxORCYY1JRdZnaBtnjjkJxgD7ZVL0nw2sCYd0yTMKTvz3nnTnOF3cDifK+kvw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.6.0.tgz", + "integrity": "sha512-5HmXvDgs8VK+74jF9y9/2FE3/OnlcKmc56tjmSrEuZjpSZOGL+fvAu+HKJBdPs9uwoP2hE6TlSUpXZ/C5jUFmQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.6.0.tgz", + "integrity": "sha512-Ps/hui3A+vMbjdqlqAowK2ZL8+BO8dBjxeWXj6npTBs3jx4wWmbPpaLuqwrQrSqIVMCnpWo238bJ1U37GhQOYg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.6.0.tgz", + "integrity": "sha512-9c6AUHgHoG+IY88MRIHupztQiQnrbqHYQjkM2btA+Bf/wQnQMuiD0Wfk1EVv3TlNT3x41uU71rn6E4xh/+zvkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.6.0.tgz", + "integrity": "sha512-yHRqS2owEXe6Hic9z6Mh1ECsCd+ODVOGvZDyciqRd21+v+o+DnXMOrw50DSpIG2sb8GPEaPPmfeCAWKPJdq46g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.6.0.tgz", + "integrity": "sha512-WhB2e/V7rqdHHWZusBSPuy5Ei8S6lSz6FE5TKKQz5h3a0O+C+mhY7vxU9b/stqvMb8beLnPY82ZrFTLKs+SrKA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.6.0.tgz", + "integrity": "sha512-ulGE6x6Oz6iAwg75T8YQSoguBWasniIbX+QWpaYPcCnDOpdWX3k+4xbEYPZVLxOuoJI+svJJPD3sEj8G7lrQ3A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.6.0.tgz", + "integrity": "sha512-tkBYKt7YQrjIJWYDnto2YgO8MRkjlMTSNoRHzsXinBqbLdeOM3L32wPZJvIZxqaLMfSlS/4sUjH/6STVP/XDLw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.6.0.tgz", + "integrity": "sha512-gIZAP23jaHjGWasY/TY6yL7NHFClf0Ga7FN+iINvk+KN94rhm94lYZhFsbYFNcA04/onvGD9kKmiJLJB2HbNwQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.6.0.tgz", + "integrity": "sha512-cA+/pXV2YkfxlIcXOQ5fSWqAzzPyD78/x5qbK/I0vUkrlYHA8TIz+MXjAbGouguKVSI4bOmkTSJ1/poVSsgt+A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-rc.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.4.tgz", + "integrity": "sha512-vRq9f4NzvbdZavhQbjkJBx7rRebDKYR9zHfO/Wg486+I7bSecdUapzCm5cyXoK+LHokTxgSq7A5baAXUZkIz0w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-rc.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.4.tgz", + "integrity": "sha512-kFgEvkWLqt3YCgKB5re9RlIrx9bRsvyVUnaTakEpOPuLGzLpLapYxE9BufJNvPg8GjT6mB1alN4yN1NjzoeM8Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-rc.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.4.tgz", + "integrity": "sha512-JXmaOJGsL/+rsmMfutcDjxWM2fTaVgCHGoXS7nE8Z3c9NAYjGqHvXrAhMUZvMpHS/k7Mg+X7n/MVKb7NYWKKww==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-rc.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.4.tgz", + "integrity": "sha512-ep3Catd6sPnHTM0P4hNEvIv5arnDvk01PfyJIJ+J3wVCG1eEaPo09tvFqdtcaTrkwQy0VWR24uz+cb4IsK53Qw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-rc.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.4.tgz", + "integrity": "sha512-LwA5ayKIpnsgXJEwWc3h8wPiS33NMIHd9BhsV92T8VetVAbGe2qXlJwNVDGHN5cOQ22R9uYvbrQir2AB+ntT2w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-rc.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.4.tgz", + "integrity": "sha512-AC1WsGdlV1MtGay/OQ4J9T7GRadVnpYRzTcygV1hKnypbYN20Yh4t6O1Sa2qRBMqv1etulUknqXjc3CTIsBu6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-rc.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.4.tgz", + "integrity": "sha512-lU+6rgXXViO61B4EudxtVMXSOfiZONR29Sys5VGSetUY7X8mg9FCKIIjcPPj8xNDeYzKl+H8F/qSKOBVFJChCQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-rc.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.4.tgz", + "integrity": "sha512-DZaN1f0PGp/bSvKhtw50pPsnln4T13ycDq1FrDWRiHmWt1JeW+UtYg9touPFf8yt993p8tS2QjybpzKNTxYEwg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-rc.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.4.tgz", + "integrity": "sha512-RnGxwZLN7fhMMAItnD6dZ7lvy+TI7ba+2V54UF4dhaWa/p8I/ys1E73KO6HmPmgz92ZkfD8TXS1IMV8+uhbR9g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0-rc.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.4.tgz", + "integrity": "sha512-6lcI79+X8klGiGd8yHuTgQRjuuJYNggmEml+RsyN596P23l/zf9FVmJ7K0KVKkFAeYEdg0iMUKyIxiV5vebDNQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-rc.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.4.tgz", + "integrity": "sha512-wz7ohsKCAIWy91blZ/1FlpPdqrsm1xpcEOQVveWoL6+aSPKL4VUcoYmmzuLTssyZxRpEwzuIxL/GDsvpjaBtOw==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^1.1.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-rc.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.4.tgz", + "integrity": "sha512-cfiMrfuWCIgsFmcVG0IPuO6qTRHvF7NuG3wngX1RZzc6dU8FuBFb+J3MIR5WrdTNozlumfgL4cvz+R4ozBCvsQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-rc.4", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.4.tgz", + "integrity": "sha512-p6UeR9y7ht82AH57qwGuFYn69S6CZ7LLKdCKy/8T3zS9VTrJei2/CGsTUV45Da4Z9Rbhc7G4gyWQ/Ioamqn09g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.4", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.4.tgz", + "integrity": "sha512-1BrrmTu0TWfOP1riA8uakjFc9bpIUGzVKETsOtzY39pPga8zELGDl8eu1Dx7/gjM5CAz14UknsUMpBO8L+YntQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz", + "integrity": "sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz", + "integrity": "sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz", + "integrity": "sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz", + "integrity": "sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz", + "integrity": "sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz", + "integrity": "sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz", + "integrity": "sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz", + "integrity": "sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz", + "integrity": "sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz", + "integrity": "sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz", + "integrity": "sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz", + "integrity": "sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz", + "integrity": "sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz", + "integrity": "sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz", + "integrity": "sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz", + "integrity": "sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz", + "integrity": "sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz", + "integrity": "sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz", + "integrity": "sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz", + "integrity": "sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz", + "integrity": "sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz", + "integrity": "sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz", + "integrity": "sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz", + "integrity": "sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz", + "integrity": "sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@schematics/angular": { + "version": "21.2.19", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-21.2.19.tgz", + "integrity": "sha512-eL+UU9eizoadhDB4YEctRmmo0A5iwrSmGzeuEa6akrq8nLGVWM8zO91HTJutkPqGQjelF+UOiOShsQSZAU9SIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "21.2.19", + "@angular-devkit/schematics": "21.2.19", + "jsonc-parser": "3.3.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@sigstore/bundle": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-4.0.0.tgz", + "integrity": "sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.5.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@sigstore/core": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-3.2.1.tgz", + "integrity": "sha512-qRsxPnCrbC/puegGxKuynfnxgLiHqWStrSjxkoB4YKqq3Z3s4cyZyj42ZdWFAEblNP65C+rBH8EuREHIXoi83g==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.5.1.tgz", + "integrity": "sha512-/ScWUhhoFasJsSRGTVBwId1loQjjnjAfE4djL6ZhrXRpNCmPTnUKF5Jokd58ILseOMjzET3UrMOtJPS9sYeI0g==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-4.1.1.tgz", + "integrity": "sha512-Hf4xglukg0XXQ2RiD5vSoLjdPe8OBUPA8XeVjUObheuDcWdYWrnH/BNmxZCzkAy68MzmNCxXLeurJvs6hcP2OQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@gar/promise-retry": "^1.0.2", + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.2.0", + "@sigstore/protobuf-specs": "^0.5.0", + "make-fetch-happen": "^15.0.4", + "proc-log": "^6.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@sigstore/tuf": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-4.0.2.tgz", + "integrity": "sha512-TCAzTy0xzdP79EnxSjq9KQ3eaR7+FmudLC6eRKknVKZbV7ZNlGLClAAQb/HMNJ5n2OBNk2GT1tEmU0xuPr+SLQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.5.0", + "tuf-js": "^4.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@sigstore/verify": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-3.1.1.tgz", + "integrity": "sha512-qv7+G3J2cc6wwFj3yKvXOamzqhMwSk1ogPGmhpS8iXllcPrJaIIBA+4HbttlHVu1pqWTdmaCH/WE7UOC51kdoA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.2.1", + "@sigstore/protobuf-specs": "^0.5.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "license": "MIT" + }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-4.1.0.tgz", + "integrity": "sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^10.1.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-2.1.4.tgz", + "integrity": "sha512-HXciTXN/sDBYWgeAD4V4s0DN0g72x5mlxQhHxtYu3Tt8BLa6MzcJZUyDVFCdtjNs3bfENVHVzOsmooTVuNgAAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "peerDependencies": { + "vite": "^6.0.0 || ^7.0.0" + } + }, + "node_modules/@vitest/expect": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", + "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", + "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.1.10", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", + "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz", + "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.1.10", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz", + "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.10", + "@vitest/utils": "4.1.10", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", + "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", + "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.10", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/abbrev": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-4.0.0.tgz", + "integrity": "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/algoliasearch": { + "version": "5.48.1", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.48.1.tgz", + "integrity": "sha512-Rf7xmeuIo7nb6S4mp4abW2faW8DauZyE2faBIKFaUfP3wnpOvNSbiI5AwVhqBNj0jPgBWEvhyCu0sLjN2q77Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/abtesting": "1.14.1", + "@algolia/client-abtesting": "5.48.1", + "@algolia/client-analytics": "5.48.1", + "@algolia/client-common": "5.48.1", + "@algolia/client-insights": "5.48.1", + "@algolia/client-personalization": "5.48.1", + "@algolia/client-query-suggestions": "5.48.1", + "@algolia/client-search": "5.48.1", + "@algolia/ingestion": "1.48.1", + "@algolia/monitoring": "1.48.1", + "@algolia/recommend": "5.48.1", + "@algolia/requester-browser-xhr": "5.48.1", + "@algolia/requester-fetch": "5.48.1", + "@algolia/requester-node-http": "5.48.1" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/ansi-escapes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.43", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.43.tgz", + "integrity": "sha512-AjYpR78kDWAY3Efj+cDTFH9t9SCoL7OoTp1BOb0mQV7S+6CiLwnWM3FyxhJtdPufDFKzmCSFoUncKjWgJEZTCQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/beasties": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/beasties/-/beasties-0.4.1.tgz", + "integrity": "sha512-2Imdcw3LznDuxAbJM26RHniOLAzE6WgrK8OuvVXCQtNBS8rsnD9zsSEa3fHl4hHpUY7BYTlrpvtPVbvu9G6neg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "css-select": "^6.0.0", + "css-what": "^7.0.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "htmlparser2": "^10.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.49", + "postcss-media-query-parser": "^0.2.3", + "postcss-safe-parser": "^7.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, + "node_modules/body-parser": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", + "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^2.0.0", + "debug": "^4.4.3", + "http-errors": "^2.0.1", + "iconv-lite": "^0.7.2", + "on-finished": "^2.4.1", + "qs": "^6.15.2", + "raw-body": "^3.0.2", + "type-is": "^2.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/body-parser/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/browserslist": { + "version": "4.28.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.6.tgz", + "integrity": "sha512-FQBYNK15VMslhLHpA7+n+n1GOlF1kId2xcCg7/j95f24AOF6VDYMNH4mFxF7KuaTdv627faazpOAjFzMrfJOUw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.42", + "caniuse-lite": "^1.0.30001803", + "electron-to-chromium": "^1.5.389", + "node-releases": "^2.0.51", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-20.0.4.tgz", + "integrity": "sha512-M3Lab8NPYlZU2exsL3bMVvMrMqgwCnMWfdZbK28bn3pK6APT/Te/I8hjRPNu1uwORY9a1eEQoifXbKPQMfMTOA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^5.0.0", + "fs-minipass": "^3.0.0", + "glob": "^13.0.0", + "lru-cache": "^11.1.0", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^13.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001806", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz", + "integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.2.0.tgz", + "integrity": "sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==", + "dev": true, + "license": "MIT" + }, + "node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.4.0.tgz", + "integrity": "sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz", + "integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^8.0.0", + "string-width": "^8.2.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", + "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-select": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-6.0.0.tgz", + "integrity": "sha512-rZZVSLle8v0+EY8QAkDWrKhpgt6SA5OtHsgBnsj6ZaLb5dmDVOWUDtQitd9ydxxvEjhewNudS6eTVU7uOyzvXw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^7.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "nth-check": "^2.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-7.0.0.tgz", + "integrity": "sha512-wD5oz5xibMOPHzy13CyGmogB3phdvcDaB5t0W/Nr5Z2O/agcB8YwOz6e2Lsp10pNDzBoDO9nVa3RGs/2BttpHQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssstyle": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-6.2.0.tgz", + "integrity": "sha512-Fm5NvhYathRnXNVndkUsCCuR63DCLVVwGOOwQw782coXFi5HhkXdu289l59HlXZBawsyNccXfWRYvLzcDCdDig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^5.0.1", + "@csstools/css-syntax-patches-for-csstree": "^1.0.28", + "css-tree": "^3.1.0", + "lru-cache": "^11.2.6" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cssstyle/node_modules/lru-cache": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/data-urls": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-7.0.0.tgz", + "integrity": "sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.393", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.393.tgz", + "integrity": "sha512-kiDJdIUawuEIcp9XoICKp1iTYDEbgguIPq526N1Q7jIQDeQ3CqoMx71025PI/7E48Ddtw2HuWsVjY7afEgNxmg==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.1.tgz", + "integrity": "sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/eventsource": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.1.0.tgz", + "integrity": "sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", + "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express-rate-limit": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.6.0.tgz", + "integrity": "sha512-XKJXDsASUOo0LLtFwW5hCcQGH0N4WQc/Rn8/Pvoia+TJFOkkFPvrtW9lZOeeNcxQJspvOIERMwiRLsVFlhHEkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "ip-address": "^10.2.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz", + "integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hono": { + "version": "4.12.31", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.31.tgz", + "integrity": "sha512-zJIHFrl6bq3RDd2YusFNCDlM8qUprxKswyi/OPzPyzKDdyBXDqWx8bZlZ7R+saTdSTatUmb3O7K4SspGPaEOQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/hosted-git-info": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.3.tgz", + "integrity": "sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^11.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", + "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.6.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/htmlparser2": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "entities": "^7.0.1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ignore-walk": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-8.0.0.tgz", + "integrity": "sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minimatch": "^10.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/immutable": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.9.tgz", + "integrity": "sha512-m8nVez3rwrgmWxtLMt1ZYXB2Lv7OKYn/disyxAlSDYAlKSlFoPPfIAmAM/M5xqL4m4C/wAPw7S2/CNaUii1Hxg==", + "dev": true, + "license": "MIT" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz", + "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/ip-address": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", + "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jose": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.3.tgz", + "integrity": "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsdom": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-28.1.0.tgz", + "integrity": "sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@acemir/cssom": "^0.9.31", + "@asamuzakjp/dom-selector": "^6.8.1", + "@bramus/specificity": "^2.4.2", + "@exodus/bytes": "^1.11.0", + "cssstyle": "^6.0.1", + "data-urls": "^7.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^6.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^8.0.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.0", + "undici": "^7.21.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.1", + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-5.0.0.tgz", + "integrity": "sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/listr2": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz", + "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^5.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/lmdb": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.5.1.tgz", + "integrity": "sha512-NYHA0MRPjvNX+vSw8Xxg6FLKxzAG+e7Pt8RqAQA/EehzHVXq9SxDqJIN3JL1hK0dweb884y8kIh6rkWvPyg9Wg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@harperfast/extended-iterable": "^1.0.3", + "msgpackr": "^1.11.2", + "node-addon-api": "^6.1.0", + "node-gyp-build-optional-packages": "5.2.2", + "ordered-binary": "^1.5.3", + "weak-lru-cache": "^1.2.2" + }, + "bin": { + "download-lmdb-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "3.5.1", + "@lmdb/lmdb-darwin-x64": "3.5.1", + "@lmdb/lmdb-linux-arm": "3.5.1", + "@lmdb/lmdb-linux-arm64": "3.5.1", + "@lmdb/lmdb-linux-x64": "3.5.1", + "@lmdb/lmdb-win32-arm64": "3.5.1", + "@lmdb/lmdb-win32-x64": "3.5.1" + } + }, + "node_modules/log-symbols": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz", + "integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0", + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/make-fetch-happen": { + "version": "15.0.6", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-15.0.6.tgz", + "integrity": "sha512-Je0fLJ0F5atA7F+eIlLzk+Wkcl57JDf4kf+EW8xiP5E31xOQxkIxTbgf1Oi1Lw9tRI9UEMRdI5Vz2xTzoNU1Jw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@gar/promise-retry": "^1.0.0", + "@npmcli/agent": "^4.0.0", + "@npmcli/redact": "^4.0.0", + "cacache": "^20.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^5.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^6.0.0", + "ssri": "^13.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-5.0.2.tgz", + "integrity": "sha512-2d0q2a8eCi2IRg/IGubCNRJoYbA1+YPXAzQVRFmB45gdGZafyivnZ5YSEfo3JikbjGxOdntGFvBQGqaSMXlAFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^2.0.0", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "optionalDependencies": { + "iconv-lite": "^0.7.2" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.7.tgz", + "integrity": "sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-sized": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-2.0.0.tgz", + "integrity": "sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/msgpackr": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.12.1.tgz", + "integrity": "sha512-4EUH9tQHnMmEgzW/MdAP0KIfa1T9AF+htl0ffe2n5vb2EKn9y2co8ccpgWko6S52Jy1PQZKwRnx5/KkYjtd9MQ==", + "dev": true, + "license": "MIT", + "optional": true, + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.4.tgz", + "integrity": "sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4" + } + }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/node-gyp": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.4.0.tgz", + "integrity": "sha512-OMcPNvqTCFUnNaBlmdgq+lfNqY7gTiSmNRDjY3uAXRyudeKZEZxu3CLtjMQrx4zZxCX2b/mpNqTtwuCJgXhHkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "graceful-fs": "^4.2.6", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "tar": "^7.5.4", + "tinyglobby": "^0.2.12", + "undici": "^6.25.0", + "which": "^6.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" + } + }, + "node_modules/node-gyp/node_modules/undici": { + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.27.0.tgz", + "integrity": "sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^4.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.51", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz", + "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/nopt": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-9.0.0.tgz", + "integrity": "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^4.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-bundled": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-5.0.0.tgz", + "integrity": "sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^5.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-install-checks": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-8.0.0.tgz", + "integrity": "sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-5.0.0.tgz", + "integrity": "sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-package-arg": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-13.0.2.tgz", + "integrity": "sha512-IciCE3SY3uE84Ld8WZU23gAPPV9rIYod4F+rc+vJ7h7cwAJt9Vk6TVsK60ry7Uj3SRS3bqRRIGuTp9YVlk6WNA==", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^7.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-packlist": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-10.0.4.tgz", + "integrity": "sha512-uMW73iajD8hiH4ZBxEV3HC+eTnppIqwakjOYuvgddnalIw2lJguKviK1pcUJDlIWm1wSJkchpDZDSVVsZEYRng==", + "dev": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^8.0.0", + "proc-log": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-11.0.3.tgz", + "integrity": "sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^8.0.0", + "npm-normalize-package-bin": "^5.0.0", + "npm-package-arg": "^13.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "19.1.1", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-19.1.1.tgz", + "integrity": "sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/redact": "^4.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^15.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^5.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^13.0.0", + "proc-log": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/nswag": { + "version": "14.7.1", + "resolved": "https://registry.npmjs.org/nswag/-/nswag-14.7.1.tgz", + "integrity": "sha512-V6LiNhRLY4EfaEWAvExAPSPHGUaVIuneA+a67zuhu00fcwR+7xxiBBTpyw82vuI4xMUh1Eq8Nwnc6iLqp/74+g==", + "dev": true, + "license": "MIT", + "bin": { + "nswag": "bin/nswag.js" + }, + "engines": { + "npm": ">=3.10.8" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obug": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz", + "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-9.3.0.tgz", + "integrity": "sha512-lBX72MWFduWEf7v7uWf5DHp9Jn5BI8bNPGuFgtXMmr2uDz2Gz2749y3am3agSDdkhHPHYmmxEGSKH85ZLGzgXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.6.2", + "cli-cursor": "^5.0.0", + "cli-spinners": "^3.2.0", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.1.0", + "log-symbols": "^7.0.1", + "stdin-discarder": "^0.3.1", + "string-width": "^8.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ordered-binary": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.6.1.tgz", + "integrity": "sha512-QkCdPooczexPLiXIrbVOPYkR3VO3T6v2OyKRkR1Xbhpy7/LAVXwahnRCgRp78Oe/Ehf0C/HATAxfSr6eA1oX+w==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/p-map": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.5.tgz", + "integrity": "sha512-e8vJF4XdVkzqqSHguEMz41mQO1wKwxKm5ENrUJQUu9kLDCtn83cxbyHZcszr4QC5zEA7WffRRC4gsTecC7J9oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pacote": { + "version": "21.5.1", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-21.5.1.tgz", + "integrity": "sha512-KvcJ9iy3crysCsgqc4+PknH/w6jkrp8JN36mpZBPwNaDRwTfMZD37YzRazNstiZUOhuF5pno9f78n9mEJBavwg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@gar/promise-retry": "^1.0.0", + "@npmcli/git": "^7.0.0", + "@npmcli/installed-package-contents": "^4.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "@npmcli/run-script": "^10.0.0", + "cacache": "^20.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^13.0.0", + "npm-packlist": "^10.0.1", + "npm-pick-manifest": "^11.0.1", + "npm-registry-fetch": "^19.0.0", + "proc-log": "^6.0.0", + "sigstore": "^4.0.0", + "ssri": "^13.0.0", + "tar": "^7.4.3" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz", + "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-html-rewriting-stream": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-8.0.0.tgz", + "integrity": "sha512-wzh11mj8KKkno1pZEu+l2EVeWsuKDfR5KNWZOTsslfUX8lPDZx77m9T0kIoAVkFtD1nx6YF8oh4BnPHvxMtNMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0", + "parse5": "^8.0.0", + "parse5-sax-parser": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-html-rewriting-stream/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parse5-sax-parser": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-8.0.0.tgz", + "integrity": "sha512-/dQ8UzHZwnrzs3EvDj6IkKrD/jIZyTlB+8XrHJvcjNgRdmWruNdN9i9RK/JtxakmlUdPwKubKPTCqvbTgzGhrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", + "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/path-to-regexp": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/piscina": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-5.2.0.tgz", + "integrity": "sha512-DszUCKeVN/5G5QKo6jAVHL8fmKnkJvQ0ACiVgY7YGCq3TUB2oznAOayvZPIAdEThvhczkXR+qm3IHsNXpFCYfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.x" + }, + "optionalDependencies": { + "@napi-rs/nice": "^1.0.4" + } + }, + "node_modules/pkce-challenge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/postcss": { + "version": "8.5.20", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.20.tgz", + "integrity": "sha512-lW616l85ucIQL+FocMmL7pQFPqBmwejrCMg+iPxyImlrANNJG9NHq/RkyCZopDhd8C3LA03PHRJDjkbGu8vvug==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.16", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss-safe-parser": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz", + "integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/prettier": { + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.5.tgz", + "integrity": "sha512-/FVl766LpUfB5vXgCYOYa0MeV/441Ia99AeICQIQFTY/Nw0roZwULcXpku5i1/m5kt/baz+s4Zogspd839HSMg==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.15.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", + "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz", + "integrity": "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/rolldown": { + "version": "1.0.0-rc.4", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.4.tgz", + "integrity": "sha512-V2tPDUrY3WSevrvU2E41ijZlpF+5PbZu4giH+VpNraaadsJGHa4fR6IFwsocVwEXDoAdIv5qgPPxgrvKAOIPtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.113.0", + "@rolldown/pluginutils": "1.0.0-rc.4" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.0-rc.4", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.4", + "@rolldown/binding-darwin-x64": "1.0.0-rc.4", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.4", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.4", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.4", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.4", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.4", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.4", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.4", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.4", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.4", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.4" + } + }, + "node_modules/rollup": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz", + "integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.62.2", + "@rollup/rollup-android-arm64": "4.62.2", + "@rollup/rollup-darwin-arm64": "4.62.2", + "@rollup/rollup-darwin-x64": "4.62.2", + "@rollup/rollup-freebsd-arm64": "4.62.2", + "@rollup/rollup-freebsd-x64": "4.62.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.2", + "@rollup/rollup-linux-arm-musleabihf": "4.62.2", + "@rollup/rollup-linux-arm64-gnu": "4.62.2", + "@rollup/rollup-linux-arm64-musl": "4.62.2", + "@rollup/rollup-linux-loong64-gnu": "4.62.2", + "@rollup/rollup-linux-loong64-musl": "4.62.2", + "@rollup/rollup-linux-ppc64-gnu": "4.62.2", + "@rollup/rollup-linux-ppc64-musl": "4.62.2", + "@rollup/rollup-linux-riscv64-gnu": "4.62.2", + "@rollup/rollup-linux-riscv64-musl": "4.62.2", + "@rollup/rollup-linux-s390x-gnu": "4.62.2", + "@rollup/rollup-linux-x64-gnu": "4.62.2", + "@rollup/rollup-linux-x64-musl": "4.62.2", + "@rollup/rollup-openbsd-x64": "4.62.2", + "@rollup/rollup-openharmony-arm64": "4.62.2", + "@rollup/rollup-win32-arm64-msvc": "4.62.2", + "@rollup/rollup-win32-ia32-msvc": "4.62.2", + "@rollup/rollup-win32-x64-gnu": "4.62.2", + "@rollup/rollup-win32-x64-msvc": "4.62.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/sass": { + "version": "1.97.3", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.97.3.tgz", + "integrity": "sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/sass/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sass/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sigstore": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-4.1.1.tgz", + "integrity": "sha512-endqECJkfhozrXMK5ngu/UAA0xVcVEFdnHJCElGaExypjW+HK5i6zu3NteLoaX/iFbRUbC3+DjttQs0GARr+5w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.2.1", + "@sigstore/protobuf-specs": "^0.5.0", + "@sigstore/sign": "^4.1.1", + "@sigstore/tuf": "^4.0.2", + "@sigstore/verify": "^3.1.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/slice-ansi": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-8.0.0.tgz", + "integrity": "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.3", + "is-fullwidth-code-point": "^5.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.9.tgz", + "integrity": "sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^10.1.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", + "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/ssri": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.1.tgz", + "integrity": "sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/std-env": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", + "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==", + "dev": true, + "license": "MIT" + }, + "node_modules/stdin-discarder": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.3.2.tgz", + "integrity": "sha512-eCPu1qRxPVkl5605OTWF8Wz40b4Mf45NY5LQmVPQ599knfs5QhASUm9GbJ5BDMDOXgrnh0wyEdvzmL//YMlw0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz", + "integrity": "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tar": { + "version": "7.5.20", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.20.tgz", + "integrity": "sha512-9FcyK4PA6+WbzlTM9WhQm6vB5W7cP7dUiPsv1g7YDwEQnQ1CGpK3MGlKk/ITVWMk05kHZuBhmVhiv8LZoy/PFQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", + "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyrainbow": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tldts": { + "version": "7.4.9", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.9.tgz", + "integrity": "sha512-3kZ8wQQ/k5DrChD4X4FVvr2D7E5uoRgAqkPyLpSCGUvqOvqu+JEdr3mwMUaVWb+vMHZaKhF5fp2PBigKsui7hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^7.4.9" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.4.9", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.9.tgz", + "integrity": "sha512-DxKfPBI52p2msTEu7MPhdpdDTBhhVQg1a/8PjQckeyAvO13eMYElX545grIp6nnTGIMZlRvFZPvFhvI/WIz2Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.2.tgz", + "integrity": "sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tuf-js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-4.1.0.tgz", + "integrity": "sha512-50QV99kCKH5P/Vs4E2Gzp7BopNV+KzTXqWeaxrfu5IQJBOULRsTIS9seSsOVT8ZnGXzCyx55nYWAi4qJzpZKEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "4.1.0", + "debug": "^4.4.3", + "make-fetch-happen": "^15.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/type-is": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", + "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==", + "dev": true, + "license": "MIT", + "dependencies": { + "content-type": "^2.0.0", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/type-is/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.28.0.tgz", + "integrity": "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-7.0.2.tgz", + "integrity": "sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz", + "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0 || ^0.28.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz", + "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.1.10", + "@vitest/mocker": "4.1.10", + "@vitest/pretty-format": "4.1.10", + "@vitest/runner": "4.1.10", + "@vitest/snapshot": "4.1.10", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.10", + "@vitest/browser-preview": "4.1.10", + "@vitest/browser-webdriverio": "4.1.10", + "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-v8": "4.1.10", + "@vitest/ui": "4.1.10", + "happy-dom": "*", + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "vite": { + "optional": false + } + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/watchpack": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/weak-lru-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", + "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/webidl-conversions": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", + "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-url": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.1.tgz", + "integrity": "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.11.0", + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", + "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.2", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz", + "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==", + "dev": true, + "license": "ISC", + "peerDependencies": { + "zod": "^3.25.28 || ^4" + } + } + } +} diff --git a/ahk-frontend/package.json b/ahk-frontend/package.json new file mode 100644 index 00000000..39dda26a --- /dev/null +++ b/ahk-frontend/package.json @@ -0,0 +1,34 @@ +{ + "name": "ahk-frontend", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test", + "generate-api": "nswag run nswag.json" + }, + "private": true, + "packageManager": "npm@10.9.8", + "dependencies": { + "@angular/common": "^21.2.0", + "@angular/compiler": "^21.2.0", + "@angular/core": "^21.2.0", + "@angular/forms": "^21.2.0", + "@angular/platform-browser": "^21.2.0", + "@angular/router": "^21.2.0", + "rxjs": "~7.8.0", + "tslib": "^2.3.0" + }, + "devDependencies": { + "@angular/build": "^21.2.8", + "@angular/cli": "^21.2.8", + "@angular/compiler-cli": "^21.2.0", + "jsdom": "^28.0.0", + "nswag": "^14.7.1", + "prettier": "^3.8.1", + "typescript": "~5.9.2", + "vitest": "^4.0.8" + } +} diff --git a/ahk-frontend/proxy.conf.js b/ahk-frontend/proxy.conf.js new file mode 100644 index 00000000..b855af1c --- /dev/null +++ b/ahk-frontend/proxy.conf.js @@ -0,0 +1,11 @@ +// Dev proxy: makes the SPA and API same-origin so the Identity cookie flows and no CORS config is needed. +// All /api/* calls (and the OIDC challenge/callback under /api/auth/external) are forwarded to the backend +// over HTTPS. `secure: false` accepts the backend's self-signed dev certificate. +module.exports = [ + { + context: ['/api'], + target: 'https://localhost:7443', + secure: false, + changeOrigin: true, + }, +]; diff --git a/ahk-frontend/public/favicon.ico b/ahk-frontend/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..57614f9c967596fad0a3989bec2b1deff33034f6 GIT binary patch literal 15086 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 Nr__JTFzvMr^FKp4S3v*( literal 0 HcmV?d00001 diff --git a/ahk-frontend/src/app/api/api-client.ts b/ahk-frontend/src/app/api/api-client.ts new file mode 100644 index 00000000..9cde2fb3 --- /dev/null +++ b/ahk-frontend/src/app/api/api-client.ts @@ -0,0 +1,804 @@ +//---------------------- +// +// Generated using the NSwag toolchain v14.7.1.0 (NJsonSchema v11.6.1.0 (Newtonsoft.Json v13.0.0.0)) (http://NSwag.org) +// +//---------------------- + +/* eslint-disable */ +// ReSharper disable InconsistentNaming + +import { mergeMap as _observableMergeMap, catchError as _observableCatch } from 'rxjs/operators'; +import { Observable, throwError as _observableThrow, of as _observableOf } from 'rxjs'; +import { Injectable, Inject, Optional, InjectionToken } from '@angular/core'; +import { HttpClient, HttpHeaders, HttpResponse, HttpResponseBase } from '@angular/common/http'; + +export const API_BASE_URL = new InjectionToken('API_BASE_URL'); + +export interface ICourseProbeClient { + getNotes(course: string): Observable; + addNote(request: CreateCourseNoteRequest, course: string): Observable; +} + +@Injectable({ + providedIn: 'root' +}) +export class CourseProbeClient implements ICourseProbeClient { + private http: HttpClient; + private baseUrl: string; + protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; + + constructor(@Inject(HttpClient) http: HttpClient, @Optional() @Inject(API_BASE_URL) baseUrl?: string) { + this.http = http; + this.baseUrl = baseUrl ?? "https://localhost:7443"; + } + + getNotes(course: string): Observable { + let url_ = this.baseUrl + "/api/{course}/probe/notes"; + if (course === undefined || course === null) + throw new globalThis.Error("The parameter 'course' must be defined."); + url_ = url_.replace("{course}", encodeURIComponent("" + course)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processGetNotes(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processGetNotes(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processGetNotes(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as CourseNoteDto[]; + return _observableOf(result200); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + addNote(request: CreateCourseNoteRequest, course: string): Observable { + let url_ = this.baseUrl + "/api/{course}/probe/notes"; + if (course === undefined || course === null) + throw new globalThis.Error("The parameter 'course' must be defined."); + url_ = url_.replace("{course}", encodeURIComponent("" + course)); + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(request); + + let options_ : any = { + body: content_, + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Content-Type": "application/json", + "Accept": "application/json" + }) + }; + + return this.http.request("post", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processAddNote(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processAddNote(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processAddNote(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as CourseNoteDto; + return _observableOf(result200); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } +} + +export interface IAuthClient { + login(request: LoginRequest): Observable; + logout(): Observable; + register(request: RegisterRequest): Observable; + me(): Observable; +} + +@Injectable({ + providedIn: 'root' +}) +export class AuthClient implements IAuthClient { + private http: HttpClient; + private baseUrl: string; + protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; + + constructor(@Inject(HttpClient) http: HttpClient, @Optional() @Inject(API_BASE_URL) baseUrl?: string) { + this.http = http; + this.baseUrl = baseUrl ?? "https://localhost:7443"; + } + + login(request: LoginRequest): Observable { + let url_ = this.baseUrl + "/api/auth/login"; + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(request); + + let options_ : any = { + body: content_, + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Content-Type": "application/json", + "Accept": "application/json" + }) + }; + + return this.http.request("post", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processLogin(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processLogin(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processLogin(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as CurrentUserResponse; + return _observableOf(result200); + })); + } else if (status === 401) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result401: any = null; + result401 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result401); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + logout(): Observable { + let url_ = this.baseUrl + "/api/auth/logout"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + }) + }; + + return this.http.request("post", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processLogout(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processLogout(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processLogout(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return _observableOf(null as any); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + register(request: RegisterRequest): Observable { + let url_ = this.baseUrl + "/api/auth/register"; + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(request); + + let options_ : any = { + body: content_, + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Content-Type": "application/json", + "Accept": "application/json" + }) + }; + + return this.http.request("post", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processRegister(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processRegister(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processRegister(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as CurrentUserResponse; + return _observableOf(result200); + })); + } else if (status === 400) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result400: any = null; + result400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result400); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + me(): Observable { + let url_ = this.baseUrl + "/api/auth/me"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processMe(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processMe(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processMe(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as CurrentUserResponse; + return _observableOf(result200); + })); + } else if (status === 401) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result401: any = null; + result401 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result401); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } +} + +export interface IExternalAuthClient { + challenge(returnUrl?: string | null | undefined): Observable; + callback(returnUrl?: string | null | undefined): Observable; +} + +@Injectable({ + providedIn: 'root' +}) +export class ExternalAuthClient implements IExternalAuthClient { + private http: HttpClient; + private baseUrl: string; + protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; + + constructor(@Inject(HttpClient) http: HttpClient, @Optional() @Inject(API_BASE_URL) baseUrl?: string) { + this.http = http; + this.baseUrl = baseUrl ?? "https://localhost:7443"; + } + + challenge(returnUrl?: string | null | undefined): Observable { + let url_ = this.baseUrl + "/api/auth/external/challenge?"; + if (returnUrl !== undefined && returnUrl !== null) + url_ += "returnUrl=" + encodeURIComponent("" + returnUrl) + "&"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/octet-stream" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processChallenge(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processChallenge(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processChallenge(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200 || status === 206) { + const contentDisposition = response.headers ? response.headers.get("content-disposition") : undefined; + let fileNameMatch = contentDisposition ? /filename\*=(?:(\\?['"])(.*?)\1|(?:[^\s]+'.*?')?([^;\n]*))/g.exec(contentDisposition) : undefined; + let fileName = fileNameMatch && fileNameMatch.length > 1 ? fileNameMatch[3] || fileNameMatch[2] : undefined; + if (fileName) { + fileName = decodeURIComponent(fileName); + } else { + fileNameMatch = contentDisposition ? /filename="?([^"]*?)"?(;|$)/g.exec(contentDisposition) : undefined; + fileName = fileNameMatch && fileNameMatch.length > 1 ? fileNameMatch[1] : undefined; + } + return _observableOf({ fileName: fileName, data: responseBlob as any, status: status, headers: _headers }); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + callback(returnUrl?: string | null | undefined): Observable { + let url_ = this.baseUrl + "/api/auth/external/callback?"; + if (returnUrl !== undefined && returnUrl !== null) + url_ += "returnUrl=" + encodeURIComponent("" + returnUrl) + "&"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/octet-stream" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processCallback(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processCallback(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processCallback(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200 || status === 206) { + const contentDisposition = response.headers ? response.headers.get("content-disposition") : undefined; + let fileNameMatch = contentDisposition ? /filename\*=(?:(\\?['"])(.*?)\1|(?:[^\s]+'.*?')?([^;\n]*))/g.exec(contentDisposition) : undefined; + let fileName = fileNameMatch && fileNameMatch.length > 1 ? fileNameMatch[3] || fileNameMatch[2] : undefined; + if (fileName) { + fileName = decodeURIComponent(fileName); + } else { + fileNameMatch = contentDisposition ? /filename="?([^"]*?)"?(;|$)/g.exec(contentDisposition) : undefined; + fileName = fileNameMatch && fileNameMatch.length > 1 ? fileNameMatch[1] : undefined; + } + return _observableOf({ fileName: fileName, data: responseBlob as any, status: status, headers: _headers }); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } +} + +export interface ICoursesAdminClient { + list(): Observable; + create(request: CreateCourseRequest): Observable; + get(id: string): Observable; +} + +@Injectable({ + providedIn: 'root' +}) +export class CoursesAdminClient implements ICoursesAdminClient { + private http: HttpClient; + private baseUrl: string; + protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; + + constructor(@Inject(HttpClient) http: HttpClient, @Optional() @Inject(API_BASE_URL) baseUrl?: string) { + this.http = http; + this.baseUrl = baseUrl ?? "https://localhost:7443"; + } + + list(): Observable { + let url_ = this.baseUrl + "/api/admin/courses"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processList(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processList(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processList(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as CourseDto[]; + return _observableOf(result200); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + create(request: CreateCourseRequest): Observable { + let url_ = this.baseUrl + "/api/admin/courses"; + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(request); + + let options_ : any = { + body: content_, + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Content-Type": "application/json", + "Accept": "application/json" + }) + }; + + return this.http.request("post", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processCreate(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processCreate(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processCreate(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 201) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result201: any = null; + result201 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as CourseDto; + return _observableOf(result201); + })); + } else if (status === 409) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result409: any = null; + result409 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result409); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + get(id: string): Observable { + let url_ = this.baseUrl + "/api/admin/courses/{id}"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processGet(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processGet(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processGet(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as CourseDto; + return _observableOf(result200); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } +} + +export interface CourseNoteDto { + id?: string; + text?: string; + createdAt?: Date; +} + +export interface CreateCourseNoteRequest { + text?: string; +} + +export interface CurrentUserResponse { + userId?: string; + userName?: string; + email?: string | undefined; + displayName?: string | undefined; + roles?: string[]; + courses?: CourseMembershipDto[]; +} + +export interface CourseMembershipDto { + slug?: string; + name?: string; + role?: string; +} + +export interface ProblemDetails { + type?: string | undefined; + title?: string | undefined; + status?: number | undefined; + detail?: string | undefined; + instance?: string | undefined; + + [key: string]: any; +} + +export interface LoginRequest { + userName: string; + password: string; + rememberMe?: boolean; +} + +export interface RegisterRequest { + userName: string; + email: string; + password: string; + displayName?: string | undefined; +} + +export interface CourseDto { + id?: string; + slug?: string; + name?: string; + gitHubOrganization?: string | undefined; + createdAt?: Date; +} + +export interface CreateCourseRequest { + slug: string; + name: string; + gitHubOrganization?: string | undefined; +} + +export interface FileResponse { + data: Blob; + status: number; + fileName?: string; + headers?: { [name: string]: any }; +} + +export class SwaggerException extends Error { + override message: string; + status: number; + response: string; + headers: { [key: string]: any; }; + result: any; + + constructor(message: string, status: number, response: string, headers: { [key: string]: any; }, result: any) { + super(); + + this.message = message; + this.status = status; + this.response = response; + this.headers = headers; + this.result = result; + } + + protected isSwaggerException = true; + + static isSwaggerException(obj: any): obj is SwaggerException { + return obj.isSwaggerException === true; + } +} + +function throwException(message: string, status: number, response: string, headers: { [key: string]: any; }, result?: any): Observable { + if (result !== null && result !== undefined) + return _observableThrow(result); + else + return _observableThrow(new SwaggerException(message, status, response, headers, null)); +} + +function blobToText(blob: any): Observable { + return new Observable((observer: any) => { + if (!blob) { + observer.next(""); + observer.complete(); + } else { + let reader = new FileReader(); + reader.onload = event => { + observer.next((event.target as any).result); + observer.complete(); + }; + reader.readAsText(blob); + } + }); +} \ No newline at end of file diff --git a/ahk-frontend/src/app/app.config.ts b/ahk-frontend/src/app/app.config.ts new file mode 100644 index 00000000..6537587b --- /dev/null +++ b/ahk-frontend/src/app/app.config.ts @@ -0,0 +1,18 @@ +import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core'; +import { provideRouter } from '@angular/router'; +import { provideHttpClient, withInterceptors } from '@angular/common/http'; + +import { routes } from './app.routes'; +import { API_BASE_URL } from './api/api-client'; +import { authInterceptor } from './core/auth/auth.interceptor'; + +export const appConfig: ApplicationConfig = { + providers: [ + provideBrowserGlobalErrorListeners(), + provideRouter(routes), + provideHttpClient(withInterceptors([authInterceptor])), + // Empty base URL => generated clients issue relative /api/... requests, served same-origin through the + // dev proxy (no CORS). In production the SPA is hosted under the same origin as the API. + { provide: API_BASE_URL, useValue: '' }, + ], +}; diff --git a/ahk-frontend/src/app/app.html b/ahk-frontend/src/app/app.html new file mode 100644 index 00000000..67e7bd4c --- /dev/null +++ b/ahk-frontend/src/app/app.html @@ -0,0 +1 @@ + diff --git a/ahk-frontend/src/app/app.routes.ts b/ahk-frontend/src/app/app.routes.ts new file mode 100644 index 00000000..a4129b10 --- /dev/null +++ b/ahk-frontend/src/app/app.routes.ts @@ -0,0 +1,40 @@ +import { Routes } from '@angular/router'; + +import { authGuard, adminGuard } from './core/auth/auth.guard'; +import { courseGuard } from './core/course/course.guard'; +import { Shell } from './layout/shell/shell'; + +export const routes: Routes = [ + { + path: 'login', + loadComponent: () => import('./features/login/login').then((m) => m.Login), + }, + { + // Host/admin context (no course segment). + path: 'admin', + component: Shell, + canActivate: [authGuard, adminGuard], + children: [ + { + path: 'courses', + loadComponent: () => import('./features/admin/courses/courses').then((m) => m.AdminCourses), + }, + { path: '', pathMatch: 'full', redirectTo: 'courses' }, + ], + }, + { + // Course context: /{course}/... + path: ':course', + component: Shell, + canActivate: [authGuard, courseGuard], + children: [ + { + path: 'dashboard', + loadComponent: () => import('./features/course/dashboard/dashboard').then((m) => m.CourseDashboard), + }, + { path: '', pathMatch: 'full', redirectTo: 'dashboard' }, + ], + }, + { path: '', pathMatch: 'full', redirectTo: 'login' }, + { path: '**', redirectTo: 'login' }, +]; diff --git a/ahk-frontend/src/app/app.scss b/ahk-frontend/src/app/app.scss new file mode 100644 index 00000000..e69de29b diff --git a/ahk-frontend/src/app/app.spec.ts b/ahk-frontend/src/app/app.spec.ts new file mode 100644 index 00000000..204c065b --- /dev/null +++ b/ahk-frontend/src/app/app.spec.ts @@ -0,0 +1,20 @@ +import { TestBed } from '@angular/core/testing'; +import { provideRouter } from '@angular/router'; +import { provideHttpClient } from '@angular/common/http'; + +import { App } from './app'; +import { routes } from './app.routes'; + +describe('App', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [App], + providers: [provideRouter(routes), provideHttpClient()], + }).compileComponents(); + }); + + it('should create the app', () => { + const fixture = TestBed.createComponent(App); + expect(fixture.componentInstance).toBeTruthy(); + }); +}); diff --git a/ahk-frontend/src/app/app.ts b/ahk-frontend/src/app/app.ts new file mode 100644 index 00000000..8a885676 --- /dev/null +++ b/ahk-frontend/src/app/app.ts @@ -0,0 +1,12 @@ +import { Component, signal } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; + +@Component({ + selector: 'app-root', + imports: [RouterOutlet], + templateUrl: './app.html', + styleUrl: './app.scss' +}) +export class App { + protected readonly title = signal('ahk-frontend'); +} diff --git a/ahk-frontend/src/app/core/auth/auth.guard.ts b/ahk-frontend/src/app/core/auth/auth.guard.ts new file mode 100644 index 00000000..98cc52ba --- /dev/null +++ b/ahk-frontend/src/app/core/auth/auth.guard.ts @@ -0,0 +1,21 @@ +import { inject } from '@angular/core'; +import { CanActivateFn, Router } from '@angular/router'; +import { map } from 'rxjs/operators'; + +import { AuthService } from './auth.service'; + +/** Requires an authenticated session; otherwise redirects to /login preserving the target URL. */ +export const authGuard: CanActivateFn = (_route, state) => { + const auth = inject(AuthService); + const router = inject(Router); + return auth.ensureLoaded().pipe( + map((user) => (user ? true : router.createUrlTree(['/login'], { queryParams: { returnUrl: state.url } }))), + ); +}; + +/** Requires the site-admin role; otherwise sends the user to their default landing. */ +export const adminGuard: CanActivateFn = () => { + const auth = inject(AuthService); + const router = inject(Router); + return auth.ensureLoaded().pipe(map(() => (auth.isAdmin() ? true : router.createUrlTree(['/login'])))); +}; diff --git a/ahk-frontend/src/app/core/auth/auth.interceptor.ts b/ahk-frontend/src/app/core/auth/auth.interceptor.ts new file mode 100644 index 00000000..4e5f85cf --- /dev/null +++ b/ahk-frontend/src/app/core/auth/auth.interceptor.ts @@ -0,0 +1,21 @@ +import { HttpErrorResponse, HttpInterceptorFn } from '@angular/common/http'; +import { inject } from '@angular/core'; +import { Router } from '@angular/router'; +import { throwError } from 'rxjs'; +import { catchError } from 'rxjs/operators'; + +/** + * Redirects to the login page on an unexpected 401. The session-probe endpoint (/api/auth/me) is exempt: + * a 401 there is the normal "not logged in yet" signal handled by the auth guard, not an error to redirect on. + */ +export const authInterceptor: HttpInterceptorFn = (req, next) => { + const router = inject(Router); + return next(req).pipe( + catchError((error: unknown) => { + if (error instanceof HttpErrorResponse && error.status === 401 && !req.url.includes('/api/auth/me')) { + void router.navigate(['/login']); + } + return throwError(() => error); + }), + ); +}; diff --git a/ahk-frontend/src/app/core/auth/auth.service.ts b/ahk-frontend/src/app/core/auth/auth.service.ts new file mode 100644 index 00000000..71da58fb --- /dev/null +++ b/ahk-frontend/src/app/core/auth/auth.service.ts @@ -0,0 +1,70 @@ +import { Injectable, computed, inject, signal } from '@angular/core'; +import { Observable, of } from 'rxjs'; +import { catchError, map, tap } from 'rxjs/operators'; + +import { AuthClient, CurrentUserResponse, LoginRequest } from '../../api/api-client'; + +/** + * Session state for the SPA. Hydrates from GET /api/auth/me (cookie-based), exposes the current user and + * derived flags as signals, and wraps the generated AuthClient for login/logout. + */ +@Injectable({ providedIn: 'root' }) +export class AuthService { + private readonly authClient = inject(AuthClient); + + private readonly user = signal(null); + private readonly loaded = signal(false); + + readonly currentUser = this.user.asReadonly(); + readonly isAuthenticated = computed(() => this.user() !== null); + readonly isAdmin = computed(() => this.user()?.roles?.includes('Admin') ?? false); + readonly courses = computed(() => this.user()?.courses ?? []); + + /** Loads the session once (cached). Returns the user, or null if not authenticated. */ + ensureLoaded(): Observable { + if (this.loaded()) { + return of(this.user()); + } + return this.authClient.me().pipe( + tap((u) => this.setUser(u)), + catchError(() => { + this.setLoggedOut(); + return of(null); + }), + ); + } + + login(userName: string, password: string): Observable { + const request: LoginRequest = { userName, password, rememberMe: true }; + return this.authClient.login(request).pipe( + tap((u) => this.setUser(u)), + map(() => true), + catchError(() => of(false)), + ); + } + + logout(): Observable { + return this.authClient.logout().pipe( + tap(() => this.setLoggedOut()), + map(() => undefined), + catchError(() => { + this.setLoggedOut(); + return of(undefined); + }), + ); + } + + isMemberOf(slug: string): boolean { + return this.isAdmin() || this.courses().some((c) => c.slug === slug); + } + + private setUser(u: CurrentUserResponse): void { + this.user.set(u); + this.loaded.set(true); + } + + private setLoggedOut(): void { + this.user.set(null); + this.loaded.set(true); + } +} diff --git a/ahk-frontend/src/app/core/course/course-context.service.ts b/ahk-frontend/src/app/core/course/course-context.service.ts new file mode 100644 index 00000000..95d5abc9 --- /dev/null +++ b/ahk-frontend/src/app/core/course/course-context.service.ts @@ -0,0 +1,24 @@ +import { Injectable, computed, inject, signal } from '@angular/core'; + +import { AuthService } from '../auth/auth.service'; + +/** + * Tracks the course the current route is scoped to (the {course} path segment). The active course record is + * derived from the user's memberships loaded in {@link AuthService}. + */ +@Injectable({ providedIn: 'root' }) +export class CourseContextService { + private readonly auth = inject(AuthService); + + private readonly slug = signal(null); + + readonly activeSlug = this.slug.asReadonly(); + readonly activeCourse = computed(() => { + const s = this.slug(); + return s ? (this.auth.courses().find((c) => c.slug === s) ?? null) : null; + }); + + setActiveSlug(slug: string | null): void { + this.slug.set(slug); + } +} diff --git a/ahk-frontend/src/app/core/course/course.guard.ts b/ahk-frontend/src/app/core/course/course.guard.ts new file mode 100644 index 00000000..f312acc8 --- /dev/null +++ b/ahk-frontend/src/app/core/course/course.guard.ts @@ -0,0 +1,31 @@ +import { inject } from '@angular/core'; +import { CanActivateFn, Router } from '@angular/router'; +import { map } from 'rxjs/operators'; + +import { AuthService } from '../auth/auth.service'; +import { CourseContextService } from './course-context.service'; + +/** + * Guards /{course}/... routes: the user must be a member of the course (or a site admin). On success the + * course context is set so the shell can display it. Backend authorization is the real gate; this avoids + * navigating into a course the user cannot access. + */ +export const courseGuard: CanActivateFn = (route) => { + const auth = inject(AuthService); + const courseContext = inject(CourseContextService); + const router = inject(Router); + const slug = route.paramMap.get('course'); + + return auth.ensureLoaded().pipe( + map((user) => { + if (!user) { + return router.createUrlTree(['/login']); + } + if (slug && auth.isMemberOf(slug)) { + courseContext.setActiveSlug(slug); + return true; + } + return router.createUrlTree(['/login']); + }), + ); +}; diff --git a/ahk-frontend/src/app/features/admin/courses/courses.html b/ahk-frontend/src/app/features/admin/courses/courses.html new file mode 100644 index 00000000..2acdce03 --- /dev/null +++ b/ahk-frontend/src/app/features/admin/courses/courses.html @@ -0,0 +1,32 @@ +
+

Courses

+ + @if (error(); as e) { +

{{ e }}

+ } + + + + + + + @for (c of courses(); track c.id) { + + + + + + + } @empty { + + } + +
SlugNameGitHub orgCreated
{{ c.slug }}{{ c.name }}{{ c.gitHubOrganization || '—' }}{{ c.createdAt | date: 'short' }}
No courses yet.
+ +

Add course

+
+ + + +
+
diff --git a/ahk-frontend/src/app/features/admin/courses/courses.scss b/ahk-frontend/src/app/features/admin/courses/courses.scss new file mode 100644 index 00000000..7771f5b4 --- /dev/null +++ b/ahk-frontend/src/app/features/admin/courses/courses.scss @@ -0,0 +1,46 @@ +.admin-courses { + max-width: 48rem; + + h1 { + font-size: 1.4rem; + } + + table { + width: 100%; + border-collapse: collapse; + margin-bottom: 1.5rem; + + th, + td { + text-align: left; + padding: 0.4rem 0.6rem; + border-bottom: 1px solid #e2e8f0; + font-size: 0.9rem; + } + } + + .new-course { + display: flex; + gap: 0.5rem; + flex-wrap: wrap; + + input { + padding: 0.45rem; + border: 1px solid #cbd5e1; + border-radius: 4px; + } + + button { + padding: 0.45rem 0.9rem; + border: 0; + border-radius: 4px; + background: #2563eb; + color: #fff; + cursor: pointer; + } + } + + .error { + color: #dc2626; + } +} diff --git a/ahk-frontend/src/app/features/admin/courses/courses.ts b/ahk-frontend/src/app/features/admin/courses/courses.ts new file mode 100644 index 00000000..6ccb0452 --- /dev/null +++ b/ahk-frontend/src/app/features/admin/courses/courses.ts @@ -0,0 +1,46 @@ +import { DatePipe } from '@angular/common'; +import { Component, OnInit, inject, signal } from '@angular/core'; +import { FormsModule } from '@angular/forms'; + +import { CoursesAdminClient, CourseDto, CreateCourseRequest } from '../../../api/api-client'; + +/** Host/admin screen: list and create courses (their connected GitHub environments come in the port). */ +@Component({ + selector: 'app-admin-courses', + imports: [FormsModule, DatePipe], + templateUrl: './courses.html', + styleUrl: './courses.scss', +}) +export class AdminCourses implements OnInit { + private readonly client = inject(CoursesAdminClient); + + protected readonly courses = signal([]); + protected readonly error = signal(null); + + protected slug = ''; + protected name = ''; + + ngOnInit(): void { + this.reload(); + } + + protected reload(): void { + this.client.list().subscribe({ + next: (list) => this.courses.set(list), + error: () => this.error.set('Failed to load courses.'), + }); + } + + protected create(): void { + this.error.set(null); + const request: CreateCourseRequest = { slug: this.slug, name: this.name }; + this.client.create(request).subscribe({ + next: () => { + this.slug = ''; + this.name = ''; + this.reload(); + }, + error: () => this.error.set('Failed to create course (slug may already exist).'), + }); + } +} diff --git a/ahk-frontend/src/app/features/course/dashboard/dashboard.html b/ahk-frontend/src/app/features/course/dashboard/dashboard.html new file mode 100644 index 00000000..a7c45c72 --- /dev/null +++ b/ahk-frontend/src/app/features/course/dashboard/dashboard.html @@ -0,0 +1,24 @@ +
+

+ @if (courseContext.activeCourse(); as course) { + {{ course.name }} + } @else { + Course + } +

+ +

Course-scoped probe notes (skeleton demo of course isolation):

+ +
    + @for (n of notes(); track n.id) { +
  • {{ n.text }} {{ n.createdAt | date: 'short' }}
  • + } @empty { +
  • No notes for this course.
  • + } +
+ +
+ + +
+
diff --git a/ahk-frontend/src/app/features/course/dashboard/dashboard.scss b/ahk-frontend/src/app/features/course/dashboard/dashboard.scss new file mode 100644 index 00000000..3b6a2570 --- /dev/null +++ b/ahk-frontend/src/app/features/course/dashboard/dashboard.scss @@ -0,0 +1,54 @@ +.dashboard { + max-width: 40rem; + + h1 { + font-size: 1.4rem; + } + + .hint { + color: #64748b; + font-size: 0.9rem; + } + + ul { + list-style: none; + padding: 0; + + li { + padding: 0.4rem 0; + border-bottom: 1px solid #e2e8f0; + + small { + color: #94a3b8; + margin-left: 0.5rem; + } + + &.empty { + color: #94a3b8; + border: 0; + } + } + } + + .new-note { + display: flex; + gap: 0.5rem; + margin-top: 1rem; + + input { + flex: 1; + padding: 0.45rem; + border: 1px solid #cbd5e1; + border-radius: 4px; + } + + button { + padding: 0.45rem 0.9rem; + border: 0; + border-radius: 4px; + background: #2563eb; + color: #fff; + cursor: pointer; + } + } +} diff --git a/ahk-frontend/src/app/features/course/dashboard/dashboard.ts b/ahk-frontend/src/app/features/course/dashboard/dashboard.ts new file mode 100644 index 00000000..ed82ef1c --- /dev/null +++ b/ahk-frontend/src/app/features/course/dashboard/dashboard.ts @@ -0,0 +1,47 @@ +import { DatePipe } from '@angular/common'; +import { Component, OnInit, inject, signal } from '@angular/core'; +import { FormsModule } from '@angular/forms'; + +import { CourseProbeClient, CourseNoteDto } from '../../../api/api-client'; +import { CourseContextService } from '../../../core/course/course-context.service'; + +/** + * Course landing page. For this skeleton it reads/writes the course-scoped probe notes to demonstrate that + * course data is confined to the active course. Real course dashboards (submissions, grades) replace it. + */ +@Component({ + selector: 'app-course-dashboard', + imports: [FormsModule, DatePipe], + templateUrl: './dashboard.html', + styleUrl: './dashboard.scss', +}) +export class CourseDashboard implements OnInit { + private readonly client = inject(CourseProbeClient); + protected readonly courseContext = inject(CourseContextService); + + protected readonly notes = signal([]); + protected text = ''; + + ngOnInit(): void { + this.reload(); + } + + protected reload(): void { + const slug = this.courseContext.activeSlug(); + if (!slug) { + return; + } + this.client.getNotes(slug).subscribe((list) => this.notes.set(list)); + } + + protected add(): void { + const slug = this.courseContext.activeSlug(); + if (!slug || !this.text.trim()) { + return; + } + this.client.addNote({ text: this.text }, slug).subscribe(() => { + this.text = ''; + this.reload(); + }); + } +} diff --git a/ahk-frontend/src/app/features/login/login.html b/ahk-frontend/src/app/features/login/login.html new file mode 100644 index 00000000..5e1aacac --- /dev/null +++ b/ahk-frontend/src/app/features/login/login.html @@ -0,0 +1,26 @@ + diff --git a/ahk-frontend/src/app/features/login/login.scss b/ahk-frontend/src/app/features/login/login.scss new file mode 100644 index 00000000..94e9074d --- /dev/null +++ b/ahk-frontend/src/app/features/login/login.scss @@ -0,0 +1,61 @@ +.login { + max-width: 20rem; + margin: 4rem auto; + display: flex; + flex-direction: column; + gap: 1rem; + + h1 { + font-size: 1.4rem; + margin: 0; + } + + form { + display: flex; + flex-direction: column; + gap: 0.75rem; + } + + label { + display: flex; + flex-direction: column; + gap: 0.25rem; + font-size: 0.9rem; + } + + input { + padding: 0.5rem; + border: 1px solid #cbd5e1; + border-radius: 4px; + } + + button { + padding: 0.55rem; + border: 0; + border-radius: 4px; + background: #2563eb; + color: #fff; + cursor: pointer; + + &:disabled { + opacity: 0.6; + cursor: default; + } + + &.oidc { + background: #475569; + } + } + + .error { + color: #dc2626; + font-size: 0.85rem; + margin: 0; + } + + .divider { + text-align: center; + color: #94a3b8; + font-size: 0.8rem; + } +} diff --git a/ahk-frontend/src/app/features/login/login.ts b/ahk-frontend/src/app/features/login/login.ts new file mode 100644 index 00000000..6590ac2e --- /dev/null +++ b/ahk-frontend/src/app/features/login/login.ts @@ -0,0 +1,54 @@ +import { Component, inject, signal } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; + +import { AuthService } from '../../core/auth/auth.service'; + +/** Local username/password login plus an "OIDC login" entry point (navigates to the backend challenge). */ +@Component({ + selector: 'app-login', + imports: [FormsModule], + templateUrl: './login.html', + styleUrl: './login.scss', +}) +export class Login { + private readonly auth = inject(AuthService); + private readonly router = inject(Router); + private readonly route = inject(ActivatedRoute); + + protected userName = ''; + protected password = ''; + protected readonly error = signal(null); + protected readonly busy = signal(false); + + protected submit(): void { + this.error.set(null); + this.busy.set(true); + this.auth.login(this.userName, this.password).subscribe((ok) => { + this.busy.set(false); + if (ok) { + this.router.navigateByUrl(this.landingUrl()); + } else { + this.error.set('Invalid username or password.'); + } + }); + } + + protected loginWithOidc(): void { + // Full-page navigation so the browser follows the OIDC redirect chain; proxied to the backend in dev. + const returnUrl = this.landingUrl(); + window.location.href = `/api/auth/external/challenge?returnUrl=${encodeURIComponent(returnUrl)}`; + } + + private landingUrl(): string { + const returnUrl = this.route.snapshot.queryParamMap.get('returnUrl'); + if (returnUrl) { + return returnUrl; + } + if (this.auth.isAdmin()) { + return '/admin/courses'; + } + const first = this.auth.courses()[0]; + return first ? `/${first.slug}/dashboard` : '/login'; + } +} diff --git a/ahk-frontend/src/app/layout/shell/shell.html b/ahk-frontend/src/app/layout/shell/shell.html new file mode 100644 index 00000000..c9f71293 --- /dev/null +++ b/ahk-frontend/src/app/layout/shell/shell.html @@ -0,0 +1,36 @@ +
+ AHK + + @if (courseContext.activeCourse(); as course) { + {{ course.name }} + } + + + + + + @if (isAdmin()) { + Admin + } + @if (user(); as u) { + {{ u.displayName || u.userName }} + } + +
+ +
+ +
diff --git a/ahk-frontend/src/app/layout/shell/shell.scss b/ahk-frontend/src/app/layout/shell/shell.scss new file mode 100644 index 00000000..aee01b24 --- /dev/null +++ b/ahk-frontend/src/app/layout/shell/shell.scss @@ -0,0 +1,47 @@ +.topbar { + display: flex; + align-items: center; + gap: 1rem; + padding: 0.75rem 1.25rem; + background: #1f2937; + color: #f9fafb; + + .brand { + font-weight: 700; + letter-spacing: 0.05em; + } + + .course { + font-weight: 600; + opacity: 0.9; + } + + .switcher { + display: flex; + align-items: center; + gap: 0.4rem; + font-size: 0.9rem; + } + + .spacer { + flex: 1 1 auto; + } + + .user { + opacity: 0.85; + } + + a.link, + a.link:visited { + color: #93c5fd; + text-decoration: none; + } + + button { + cursor: pointer; + } +} + +.content { + padding: 1.5rem; +} diff --git a/ahk-frontend/src/app/layout/shell/shell.ts b/ahk-frontend/src/app/layout/shell/shell.ts new file mode 100644 index 00000000..1912f010 --- /dev/null +++ b/ahk-frontend/src/app/layout/shell/shell.ts @@ -0,0 +1,30 @@ +import { Component, inject } from '@angular/core'; +import { Router, RouterLink, RouterOutlet } from '@angular/router'; + +import { AuthService } from '../../core/auth/auth.service'; +import { CourseContextService } from '../../core/course/course-context.service'; + +/** Authenticated app frame: header with the active course, a course switcher, admin link and logout. */ +@Component({ + selector: 'app-shell', + imports: [RouterOutlet, RouterLink], + templateUrl: './shell.html', + styleUrl: './shell.scss', +}) +export class Shell { + private readonly auth = inject(AuthService); + private readonly router = inject(Router); + protected readonly courseContext = inject(CourseContextService); + + protected readonly user = this.auth.currentUser; + protected readonly isAdmin = this.auth.isAdmin; + protected readonly courses = this.auth.courses; + + protected switch(slug: string): void { + void this.router.navigate([slug, 'dashboard']); + } + + protected logout(): void { + this.auth.logout().subscribe(() => this.router.navigate(['/login'])); + } +} diff --git a/ahk-frontend/src/index.html b/ahk-frontend/src/index.html new file mode 100644 index 00000000..8c0eb582 --- /dev/null +++ b/ahk-frontend/src/index.html @@ -0,0 +1,13 @@ + + + + + AhkFrontend + + + + + + + + diff --git a/ahk-frontend/src/main.ts b/ahk-frontend/src/main.ts new file mode 100644 index 00000000..5df75f9c --- /dev/null +++ b/ahk-frontend/src/main.ts @@ -0,0 +1,6 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; +import { App } from './app/app'; + +bootstrapApplication(App, appConfig) + .catch((err) => console.error(err)); diff --git a/ahk-frontend/src/styles.scss b/ahk-frontend/src/styles.scss new file mode 100644 index 00000000..90d4ee00 --- /dev/null +++ b/ahk-frontend/src/styles.scss @@ -0,0 +1 @@ +/* You can add global styles to this file, and also import other style files */ diff --git a/ahk-frontend/tsconfig.app.json b/ahk-frontend/tsconfig.app.json new file mode 100644 index 00000000..264f459b --- /dev/null +++ b/ahk-frontend/tsconfig.app.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "include": [ + "src/**/*.ts" + ], + "exclude": [ + "src/**/*.spec.ts" + ] +} diff --git a/ahk-frontend/tsconfig.json b/ahk-frontend/tsconfig.json new file mode 100644 index 00000000..2ab74427 --- /dev/null +++ b/ahk-frontend/tsconfig.json @@ -0,0 +1,33 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "compileOnSave": false, + "compilerOptions": { + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "isolatedModules": true, + "experimentalDecorators": true, + "importHelpers": true, + "target": "ES2022", + "module": "preserve" + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + }, + "files": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/ahk-frontend/tsconfig.spec.json b/ahk-frontend/tsconfig.spec.json new file mode 100644 index 00000000..d3837063 --- /dev/null +++ b/ahk-frontend/tsconfig.spec.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "vitest/globals" + ] + }, + "include": [ + "src/**/*.d.ts", + "src/**/*.spec.ts" + ] +} From 9130776bbdc48aad5b6ca296652c7632bd708702 Mon Sep 17 00:00:00 2001 From: Bence Kovari Date: Fri, 24 Jul 2026 13:28:38 +0200 Subject: [PATCH 02/19] feat: add health and user management features - Implement health check page for site administration with detailed reports on course integrations. - Create user management interface allowing admins to add, edit, and delete users, as well as manage course assignments. - Introduce no-access page for users without course assignments. - Develop shared health chain component to visualize integration statuses. - Add corresponding styles for new components and pages. --- .claude/settings.json | 67 +- CLAUDE.md | 49 +- .../Ahk.Web.Data/ApplicationDbContext.cs | 150 +- .../Ahk.Web.Data/Entities/ApplicationRole.cs | 2 +- .../Ahk.Web.Data/Entities/ApplicationUser.cs | 15 +- ahk-backend/Ahk.Web.Data/Entities/Course.cs | 19 +- .../Entities/CourseGitHubConfig.cs | 39 + .../Ahk.Web.Data/Entities/CourseMembership.cs | 4 +- .../Ahk.Web.Data/Entities/CourseNote.cs | 19 - .../Entities/CourseWebhookToken.cs | 31 + .../Ahk.Web.Data/Entities/GradeRecord.cs | 67 + .../Ahk.Web.Data/Entities/ICourseScoped.cs | 2 +- ahk-backend/Ahk.Web.Data/Entities/Student.cs | 27 + .../Ahk.Web.Data/Entities/Submission.cs | 34 + .../Ahk.Web.Data/Entities/SubmissionEvent.cs | 64 + .../Ahk.Web.Data/ICurrentCourseProvider.cs | 4 +- .../20260720133652_InitialCreate.Designer.cs | 394 ---- .../20260720133652_InitialCreate.cs | 310 --- .../20260721170210_InitialCreate.Designer.cs | 836 ++++++++ .../20260721170210_InitialCreate.cs | 593 ++++++ .../20260722162506_OidcUserClaims.Designer.cs | 847 ++++++++ .../20260722162506_OidcUserClaims.cs | 69 + ...260723112811_GitHubAccessToken.Designer.cs | 854 ++++++++ .../20260723112811_GitHubAccessToken.cs | 40 + .../ApplicationDbContextModelSnapshot.cs | 552 +++++- ahk-backend/Ahk.Web.Data/Normalize.cs | 16 + .../Ahk.Web.Data/Seed/DevDataSeeder.cs | 140 +- .../Ahk.Web.Import/Ahk.Web.Import.csproj | 18 + ahk-backend/Ahk.Web.Import/CosmosDocuments.cs | 91 + ahk-backend/Ahk.Web.Import/ImportOptions.cs | 70 + ahk-backend/Ahk.Web.Import/Importer.cs | 258 +++ ahk-backend/Ahk.Web.Import/Program.cs | 46 + .../Ahk.Web.Server.Tests/ApiSmokeTests.cs | 46 +- .../Ahk.Web.Server.Tests/CourseHealthTests.cs | 134 ++ .../CourseScopingTests.cs | 115 +- .../ExternalClaimsMapperTests.cs | 118 ++ .../GradeLogicParityTests.cs | 118 ++ .../StatusProjectionTests.cs | 101 + .../Admin/CourseHealthAdminController.cs | 39 + .../Admin/CoursesAdminController.cs | 336 +++- .../Ahk.Web.Server/Admin/Dto/CourseDto.cs | 160 +- .../Ahk.Web.Server/Admin/Dto/UserDto.cs | 103 + .../Admin/UsersAdminController.cs | 310 +++ .../Ahk.Web.Server/Ahk.Web.Server.csproj | 1 + .../Ahk.Web.Server/Auth/AuthController.cs | 88 +- .../Ahk.Web.Server/Auth/BmeClaimTypes.cs | 14 + .../Auth/Dto/CurrentUserResponse.cs | 12 +- .../Ahk.Web.Server/Auth/Dto/LoginRequest.cs | 13 + .../Ahk.Web.Server/Auth/Dto/LogoutResponse.cs | 11 + .../Auth/ExternalAuthController.cs | 77 +- .../Auth/ExternalClaimsMapper.cs | 79 + .../Configuration/OidcOptions.cs | 50 +- .../CourseMembershipAuthorizationHandler.cs | 5 +- .../CourseContext/CurrentCourseProvider.cs | 4 +- .../Courses/CourseProbeController.cs | 62 - .../Courses/GradesController.cs | 43 + .../Courses/SubmissionStatusesController.cs | 30 + .../MockOidc/MockOidcEndpoints.cs | 183 ++ .../MockOidc/MockOidcSigningKey.cs | 46 + .../Ahk.Web.Server/MockOidc/MockOidcUsers.cs | 79 + ahk-backend/Ahk.Web.Server/Program.cs | 320 ++- .../appsettings.Development.json | 12 +- ahk-backend/Ahk.Web.Server/appsettings.json | 10 +- .../Ahk.Web.Services/Ahk.Web.Services.csproj | 25 + .../Courses/CourseResolutionService.cs | 70 + .../Courses/WebhookTokenService.cs | 116 ++ .../Ahk.Web.Services/Grading/CsvExporter.cs | 52 + .../Grading/Dto/FinalStudentGrade.cs | 17 + .../Grading/Dto/GradeInputs.cs | 66 + .../Grading/GradeListingService.cs | 56 + .../Ahk.Web.Services/Grading/GradeService.cs | 152 ++ .../Health/CiCallbackTokenHealthCheck.cs | 52 + .../Health/CourseHealthModels.cs | 89 + .../Health/CourseHealthService.cs | 91 + .../Health/GitHubAccessHealthCheck.cs | 118 ++ .../Health/ICourseHealthCheck.cs | 26 + .../Health/WebhookConfigurationHealthCheck.cs | 48 + .../ServiceCollectionExtensions.cs | 53 + .../StatusTracking/Dto/RepositoryStatus.cs | 39 + .../StatusTracking/StatusTrackingService.cs | 85 + .../StatusTracking/SubmissionEventService.cs | 57 + .../Submissions/SubmissionResolver.cs | 67 + ahk-backend/Ahk.Web.slnx | 2 + ahk-backend/README.md | 108 +- ahk-frontend/README.md | 38 +- .../BME_AUT_logo_BLACK-eng.eps | Bin 0 -> 488422 bytes .../BME_AUT_logo_BLACK-eng.png | Bin 0 -> 53178 bytes .../BME_AUT_logo_COLOR-eng.png | Bin 0 -> 56097 bytes .../BME_AUT_logo_COLOR_CMYK-eng.eps | Bin 0 -> 488550 bytes .../BME_AUT_logo_COLOR_Pantone202-eng.eps | Bin 0 -> 488562 bytes .../BME_AUT_logo_WHITE-eng.eps | Bin 0 -> 476278 bytes .../BME_AUT_logo_WHITE-eng.png | Bin 0 -> 54159 bytes .../BME_AUT_logo_BLACK-hun.eps | Bin 0 -> 492686 bytes .../BME_AUT_logo_BLACK-hun.png | Bin 0 -> 46176 bytes .../BME_AUT_logo_COLOR-hun.png | Bin 0 -> 50244 bytes .../BME_AUT_logo_COLOR_CMYK-hun.eps | Bin 0 -> 492938 bytes .../BME_AUT_logo_COLOR_Pantone202-hun.eps | Bin 0 -> 492846 bytes .../BME_AUT_logo_WHITE-hun.eps | Bin 0 -> 481542 bytes .../BME_AUT_logo_WHITE-hun.png | Bin 0 -> 51932 bytes .../BME-AUT logo hungarian/TeamsLogo.png | Bin 0 -> 28141 bytes .../BME_AUT_logo_only_BLACK-hun.png | Bin 0 -> 29457 bytes .../BME_AUT_logo_only_COLOR-hun.png | Bin 0 -> 31287 bytes .../BME_AUT_logo_only_WHITE-hun.png | Bin 0 -> 31369 bytes ahk-frontend/brand/README.md | 60 + .../brand/eduID/eduid_logo_color_rect.png | Bin 0 -> 12864 bytes .../brand/eduID/eduid_logo_color_square.png | Bin 0 -> 8477 bytes ahk-frontend/proxy.conf.js | 17 +- ahk-frontend/public/bme-aut-logo-white.png | Bin 0 -> 54159 bytes ahk-frontend/public/bme-aut-logo.png | Bin 0 -> 56097 bytes ahk-frontend/public/bme-aut-mark.png | Bin 0 -> 31287 bytes ahk-frontend/public/eduid-logo.png | Bin 0 -> 12864 bytes ahk-frontend/src/app/api/api-client.ts | 1734 ++++++++++++++++- ahk-frontend/src/app/app.routes.ts | 27 +- ahk-frontend/src/app/core/api-error.ts | 34 + ahk-frontend/src/app/core/auth/auth.guard.ts | 28 +- .../src/app/core/auth/auth.service.ts | 39 +- .../app/core/course/course-context.service.ts | 4 +- .../src/app/core/course/course.guard.ts | 9 +- .../features/admin/courses/course-editor.html | 408 ++++ .../features/admin/courses/course-editor.scss | 110 ++ .../features/admin/courses/course-editor.ts | 323 +++ .../app/features/admin/courses/courses.html | 169 +- .../app/features/admin/courses/courses.scss | 53 +- .../src/app/features/admin/courses/courses.ts | 143 +- .../src/app/features/admin/health/health.html | 77 + .../src/app/features/admin/health/health.scss | 67 + .../src/app/features/admin/health/health.ts | 100 + .../src/app/features/admin/users/users.html | 257 +++ .../src/app/features/admin/users/users.scss | 85 + .../src/app/features/admin/users/users.ts | 249 +++ .../features/course/dashboard/dashboard.html | 173 +- .../features/course/dashboard/dashboard.scss | 103 +- .../features/course/dashboard/dashboard.ts | 155 +- .../src/app/features/login/login.html | 80 +- .../src/app/features/login/login.scss | 155 +- ahk-frontend/src/app/features/login/login.ts | 43 +- .../src/app/features/no-access/no-access.html | 14 + .../src/app/features/no-access/no-access.scss | 13 + .../src/app/features/no-access/no-access.ts | 21 + ahk-frontend/src/app/layout/shell/shell.html | 88 +- ahk-frontend/src/app/layout/shell/shell.scss | 215 +- ahk-frontend/src/app/layout/shell/shell.ts | 24 +- .../app/shared/health-chain/health-chain.html | 35 + .../app/shared/health-chain/health-chain.scss | 110 ++ .../app/shared/health-chain/health-chain.ts | 45 + ahk-frontend/src/index.html | 2 +- ahk-frontend/src/styles.scss | 555 +++++- 147 files changed, 14222 insertions(+), 1475 deletions(-) create mode 100644 ahk-backend/Ahk.Web.Data/Entities/CourseGitHubConfig.cs delete mode 100644 ahk-backend/Ahk.Web.Data/Entities/CourseNote.cs create mode 100644 ahk-backend/Ahk.Web.Data/Entities/CourseWebhookToken.cs create mode 100644 ahk-backend/Ahk.Web.Data/Entities/GradeRecord.cs create mode 100644 ahk-backend/Ahk.Web.Data/Entities/Student.cs create mode 100644 ahk-backend/Ahk.Web.Data/Entities/Submission.cs create mode 100644 ahk-backend/Ahk.Web.Data/Entities/SubmissionEvent.cs delete mode 100644 ahk-backend/Ahk.Web.Data/Migrations/20260720133652_InitialCreate.Designer.cs delete mode 100644 ahk-backend/Ahk.Web.Data/Migrations/20260720133652_InitialCreate.cs create mode 100644 ahk-backend/Ahk.Web.Data/Migrations/20260721170210_InitialCreate.Designer.cs create mode 100644 ahk-backend/Ahk.Web.Data/Migrations/20260721170210_InitialCreate.cs create mode 100644 ahk-backend/Ahk.Web.Data/Migrations/20260722162506_OidcUserClaims.Designer.cs create mode 100644 ahk-backend/Ahk.Web.Data/Migrations/20260722162506_OidcUserClaims.cs create mode 100644 ahk-backend/Ahk.Web.Data/Migrations/20260723112811_GitHubAccessToken.Designer.cs create mode 100644 ahk-backend/Ahk.Web.Data/Migrations/20260723112811_GitHubAccessToken.cs create mode 100644 ahk-backend/Ahk.Web.Data/Normalize.cs create mode 100644 ahk-backend/Ahk.Web.Import/Ahk.Web.Import.csproj create mode 100644 ahk-backend/Ahk.Web.Import/CosmosDocuments.cs create mode 100644 ahk-backend/Ahk.Web.Import/ImportOptions.cs create mode 100644 ahk-backend/Ahk.Web.Import/Importer.cs create mode 100644 ahk-backend/Ahk.Web.Import/Program.cs create mode 100644 ahk-backend/Ahk.Web.Server.Tests/CourseHealthTests.cs create mode 100644 ahk-backend/Ahk.Web.Server.Tests/ExternalClaimsMapperTests.cs create mode 100644 ahk-backend/Ahk.Web.Server.Tests/GradeLogicParityTests.cs create mode 100644 ahk-backend/Ahk.Web.Server.Tests/StatusProjectionTests.cs create mode 100644 ahk-backend/Ahk.Web.Server/Admin/CourseHealthAdminController.cs create mode 100644 ahk-backend/Ahk.Web.Server/Admin/Dto/UserDto.cs create mode 100644 ahk-backend/Ahk.Web.Server/Admin/UsersAdminController.cs create mode 100644 ahk-backend/Ahk.Web.Server/Auth/BmeClaimTypes.cs create mode 100644 ahk-backend/Ahk.Web.Server/Auth/Dto/LogoutResponse.cs create mode 100644 ahk-backend/Ahk.Web.Server/Auth/ExternalClaimsMapper.cs delete mode 100644 ahk-backend/Ahk.Web.Server/Courses/CourseProbeController.cs create mode 100644 ahk-backend/Ahk.Web.Server/Courses/GradesController.cs create mode 100644 ahk-backend/Ahk.Web.Server/Courses/SubmissionStatusesController.cs create mode 100644 ahk-backend/Ahk.Web.Server/MockOidc/MockOidcEndpoints.cs create mode 100644 ahk-backend/Ahk.Web.Server/MockOidc/MockOidcSigningKey.cs create mode 100644 ahk-backend/Ahk.Web.Server/MockOidc/MockOidcUsers.cs create mode 100644 ahk-backend/Ahk.Web.Services/Ahk.Web.Services.csproj create mode 100644 ahk-backend/Ahk.Web.Services/Courses/CourseResolutionService.cs create mode 100644 ahk-backend/Ahk.Web.Services/Courses/WebhookTokenService.cs create mode 100644 ahk-backend/Ahk.Web.Services/Grading/CsvExporter.cs create mode 100644 ahk-backend/Ahk.Web.Services/Grading/Dto/FinalStudentGrade.cs create mode 100644 ahk-backend/Ahk.Web.Services/Grading/Dto/GradeInputs.cs create mode 100644 ahk-backend/Ahk.Web.Services/Grading/GradeListingService.cs create mode 100644 ahk-backend/Ahk.Web.Services/Grading/GradeService.cs create mode 100644 ahk-backend/Ahk.Web.Services/Health/CiCallbackTokenHealthCheck.cs create mode 100644 ahk-backend/Ahk.Web.Services/Health/CourseHealthModels.cs create mode 100644 ahk-backend/Ahk.Web.Services/Health/CourseHealthService.cs create mode 100644 ahk-backend/Ahk.Web.Services/Health/GitHubAccessHealthCheck.cs create mode 100644 ahk-backend/Ahk.Web.Services/Health/ICourseHealthCheck.cs create mode 100644 ahk-backend/Ahk.Web.Services/Health/WebhookConfigurationHealthCheck.cs create mode 100644 ahk-backend/Ahk.Web.Services/ServiceCollectionExtensions.cs create mode 100644 ahk-backend/Ahk.Web.Services/StatusTracking/Dto/RepositoryStatus.cs create mode 100644 ahk-backend/Ahk.Web.Services/StatusTracking/StatusTrackingService.cs create mode 100644 ahk-backend/Ahk.Web.Services/StatusTracking/SubmissionEventService.cs create mode 100644 ahk-backend/Ahk.Web.Services/Submissions/SubmissionResolver.cs create mode 100644 ahk-frontend/brand/BME-AUT logo english/BME_AUT_logo_BLACK-eng.eps create mode 100644 ahk-frontend/brand/BME-AUT logo english/BME_AUT_logo_BLACK-eng.png create mode 100644 ahk-frontend/brand/BME-AUT logo english/BME_AUT_logo_COLOR-eng.png create mode 100644 ahk-frontend/brand/BME-AUT logo english/BME_AUT_logo_COLOR_CMYK-eng.eps create mode 100644 ahk-frontend/brand/BME-AUT logo english/BME_AUT_logo_COLOR_Pantone202-eng.eps create mode 100644 ahk-frontend/brand/BME-AUT logo english/BME_AUT_logo_WHITE-eng.eps create mode 100644 ahk-frontend/brand/BME-AUT logo english/BME_AUT_logo_WHITE-eng.png create mode 100644 ahk-frontend/brand/BME-AUT logo hungarian/BME_AUT_logo_BLACK-hun.eps create mode 100644 ahk-frontend/brand/BME-AUT logo hungarian/BME_AUT_logo_BLACK-hun.png create mode 100644 ahk-frontend/brand/BME-AUT logo hungarian/BME_AUT_logo_COLOR-hun.png create mode 100644 ahk-frontend/brand/BME-AUT logo hungarian/BME_AUT_logo_COLOR_CMYK-hun.eps create mode 100644 ahk-frontend/brand/BME-AUT logo hungarian/BME_AUT_logo_COLOR_Pantone202-hun.eps create mode 100644 ahk-frontend/brand/BME-AUT logo hungarian/BME_AUT_logo_WHITE-hun.eps create mode 100644 ahk-frontend/brand/BME-AUT logo hungarian/BME_AUT_logo_WHITE-hun.png create mode 100644 ahk-frontend/brand/BME-AUT logo hungarian/TeamsLogo.png create mode 100644 ahk-frontend/brand/BME-AUT logo only/BME_AUT_logo_only_BLACK-hun.png create mode 100644 ahk-frontend/brand/BME-AUT logo only/BME_AUT_logo_only_COLOR-hun.png create mode 100644 ahk-frontend/brand/BME-AUT logo only/BME_AUT_logo_only_WHITE-hun.png create mode 100644 ahk-frontend/brand/README.md create mode 100644 ahk-frontend/brand/eduID/eduid_logo_color_rect.png create mode 100644 ahk-frontend/brand/eduID/eduid_logo_color_square.png create mode 100644 ahk-frontend/public/bme-aut-logo-white.png create mode 100644 ahk-frontend/public/bme-aut-logo.png create mode 100644 ahk-frontend/public/bme-aut-mark.png create mode 100644 ahk-frontend/public/eduid-logo.png create mode 100644 ahk-frontend/src/app/core/api-error.ts create mode 100644 ahk-frontend/src/app/features/admin/courses/course-editor.html create mode 100644 ahk-frontend/src/app/features/admin/courses/course-editor.scss create mode 100644 ahk-frontend/src/app/features/admin/courses/course-editor.ts create mode 100644 ahk-frontend/src/app/features/admin/health/health.html create mode 100644 ahk-frontend/src/app/features/admin/health/health.scss create mode 100644 ahk-frontend/src/app/features/admin/health/health.ts create mode 100644 ahk-frontend/src/app/features/admin/users/users.html create mode 100644 ahk-frontend/src/app/features/admin/users/users.scss create mode 100644 ahk-frontend/src/app/features/admin/users/users.ts create mode 100644 ahk-frontend/src/app/features/no-access/no-access.html create mode 100644 ahk-frontend/src/app/features/no-access/no-access.scss create mode 100644 ahk-frontend/src/app/features/no-access/no-access.ts create mode 100644 ahk-frontend/src/app/shared/health-chain/health-chain.html create mode 100644 ahk-frontend/src/app/shared/health-chain/health-chain.scss create mode 100644 ahk-frontend/src/app/shared/health-chain/health-chain.ts diff --git a/.claude/settings.json b/.claude/settings.json index 2d676dc0..9c607d4c 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -19,7 +19,72 @@ "Read(//c/Users/beny314/.claude/projects/c--Source-ahk-github-automation/memory/**)", "Bash(echo \"=== remaining in memory dir ===\")", "Bash(ls -A C:/Users/beny314/.claude/projects/c--Source-ahk-github-automation/memory)", - "Bash(echo \"\\(empty\\)\")" + "Bash(echo \"\\(empty\\)\")", + "Bash(curl -sk -c C:/Users/beny314/AppData/Local/Temp/claude/c--Source-ahk-github-automation/8d87f62d-6109-437b-91ea-1cb12635e036/scratchpad/c_admin.txt -X POST https://localhost:7443/api/auth/login -H 'Content-Type: application/json' -d '{\"userName\":\"admin\",\"password\":\"Admin123!\"}')", + "Bash(curl -sk -b C:/Users/beny314/AppData/Local/Temp/claude/c--Source-ahk-github-automation/8d87f62d-6109-437b-91ea-1cb12635e036/scratchpad/c_admin.txt https://localhost:7443/api/admin/courses)", + "Bash(curl -sk -c C:/Users/beny314/AppData/Local/Temp/claude/c--Source-ahk-github-automation/8d87f62d-6109-437b-91ea-1cb12635e036/scratchpad/c_inst.txt -X POST https://localhost:7443/api/auth/login -H 'Content-Type: application/json' -d '{\"userName\":\"instructor\",\"password\":\"Instructor123!\"}')", + "Bash(curl -sk -b C:/Users/beny314/AppData/Local/Temp/claude/c--Source-ahk-github-automation/8d87f62d-6109-437b-91ea-1cb12635e036/scratchpad/c_inst.txt https://localhost:7443/api/viaubc01/probe/notes)", + "Bash(curl -sk -b C:/Users/beny314/AppData/Local/Temp/claude/c--Source-ahk-github-automation/8d87f62d-6109-437b-91ea-1cb12635e036/scratchpad/c_inst.txt -o /dev/null -w 'cross-course viaubb01 → %{http_code} \\(expect 403\\)\\\\n' https://localhost:7443/api/viaubb01/probe/notes)", + "PowerShell(sqlcmd -S \"\\(localdb\\)\\\\MSSQLLocalDB\" -d AhkWeb -Q $q -h -1 -W)", + "Bash(dotnet new *)", + "Bash(rm -f Ahk.Web.Services/Class1.cs)", + "Bash(dotnet sln *)", + "Bash(curl -sk -c C:/Users/beny314/AppData/Local/Temp/claude/c--Source-ahk-github-automation/8d87f62d-6109-437b-91ea-1cb12635e036/scratchpad/adm.txt -X POST https://localhost:7443/api/auth/login -H 'Content-Type: application/json' -d '{\"userName\":\"admin\",\"password\":\"Admin123!\"}' -o /dev/null)", + "Bash(curl -sk -b C:/Users/beny314/AppData/Local/Temp/claude/c--Source-ahk-github-automation/8d87f62d-6109-437b-91ea-1cb12635e036/scratchpad/adm.txt https://localhost:7443/api/viaubb01/statuses)", + "Bash(curl -sk -b C:/Users/beny314/AppData/Local/Temp/claude/c--Source-ahk-github-automation/8d87f62d-6109-437b-91ea-1cb12635e036/scratchpad/adm.txt https://localhost:7443/api/viaubb01/grades)", + "Bash(curl -sk -b C:/Users/beny314/AppData/Local/Temp/claude/c--Source-ahk-github-automation/8d87f62d-6109-437b-91ea-1cb12635e036/scratchpad/adm.txt https://localhost:7443/api/viaubb01/grades/csv)", + "Bash(curl -sk -b C:/Users/beny314/AppData/Local/Temp/claude/c--Source-ahk-github-automation/8d87f62d-6109-437b-91ea-1cb12635e036/scratchpad/adm.txt https://localhost:7443/api/viaubc01/grades)", + "Bash(curl -sk -c C:/Users/beny314/AppData/Local/Temp/claude/c--Source-ahk-github-automation/8d87f62d-6109-437b-91ea-1cb12635e036/scratchpad/ins.txt -X POST https://localhost:7443/api/auth/login -H 'Content-Type: application/json' -d '{\"userName\":\"instructor\",\"password\":\"Instructor123!\"}' -o /dev/null)", + "Bash(curl -sk -b C:/Users/beny314/AppData/Local/Temp/claude/c--Source-ahk-github-automation/8d87f62d-6109-437b-91ea-1cb12635e036/scratchpad/ins.txt -o /dev/null -w ' /api/viaubb01/grades -> %{http_code} \\(expect 403\\)\\\\n' https://localhost:7443/api/viaubb01/grades)", + "Bash(curl -sk -b C:/Users/beny314/AppData/Local/Temp/claude/c--Source-ahk-github-automation/8d87f62d-6109-437b-91ea-1cb12635e036/scratchpad/ins.txt -o /dev/null -w ' /api/viaubc01/statuses -> %{http_code} \\(expect 200\\)\\\\n' https://localhost:7443/api/viaubc01/statuses)", + "Bash(curl -sk -c C:/Users/beny314/AppData/Local/Temp/claude/c--Source-ahk-github-automation/8d87f62d-6109-437b-91ea-1cb12635e036/scratchpad/p.txt -X POST https://localhost:4200/api/auth/login -H 'Content-Type: application/json' -d '{\"userName\":\"admin\",\"password\":\"Admin123!\"}' -o /dev/null -w 'login via proxy -> %{http_code}\\\\n')", + "Bash(curl -sk -b C:/Users/beny314/AppData/Local/Temp/claude/c--Source-ahk-github-automation/8d87f62d-6109-437b-91ea-1cb12635e036/scratchpad/p.txt https://localhost:4200/api/viaubb01/statuses -w '\\\\nHTTP %{http_code}\\\\n')", + "Bash(grep -rl \"MapUniqueJsonKey\" \"C:/Program Files/dotnet/packs/Microsoft.AspNetCore.App.Ref/\" 2>/dev/null | head -3 *)", + "Read(//c/Program Files/dotnet/packs/Microsoft.AspNetCore.App.Ref/**)", + "Bash(DLL=\"C:/Program Files/dotnet/shared/Microsoft.AspNetCore.App/10.0.7/Microsoft.AspNetCore.Authentication.OAuth.dll\" *)", + "Read(//c/Program Files/dotnet/shared/Microsoft.AspNetCore.App/10.0.7/**)", + "Bash(ls ~/.nuget/packages/ 2>/dev/null | grep -i -E \"octokit|github\" ; echo \"---\"; cd ahk-frontend && cat package.json)", + "Read(//c/Users/beny314/.nuget/packages/**)", + "Read(//c/Users/beny314/.nuget/packages/octokit/**)", + "Read(//c/Users/beny314/.nuget/packages/microsoft.extensions.http/**)", + "Read(//c/Program Files/Microsoft SQL Server//**)", + "Bash(cp Ahk.Web.Services/Ahk.Web.Services.csproj /tmp/svc.bak)", + "Bash(ls -la ~/.claude/ 2>/dev/null | head -40; echo \"=== plugins ===\"; ls -la ~/.claude/plugins/ 2>/dev/null | head -40)", + "Read(//c/Users/beny314/.claude/**)", + "Read(//c/Users/beny314/.claude/plugins/**)", + "Bash(cd ~/.claude/plugins && cat known_marketplaces.json && echo \"=== installed ===\" && cat installed_plugins.json && echo \"=== marketplaces/ ===\" && ls marketplaces/ && echo \"=== cache/ ===\" && ls cache/ 2>/dev/null && echo \"=== repos/ ===\" && ls repos/ 2>/dev/null)", + "Bash(python -c ' *)", + "Bash(dotnet run *)", + "Bash(curl -sk https://localhost:7443/swagger/v1/swagger.json -o /dev/null)", + "Bash(curl -sk https://localhost:7443/swagger/v1/swagger.json -o /dev/null -w \"%{http_code}\\\\n\")", + "Bash(rm -f c.txt)", + "Bash(curl -sk -c c.txt -X POST https://localhost:7443/api/auth/login -H \"Content-Type: application/json\" -d '{\"userName\":\"admin\",\"password\":\"Admin123!\",\"rememberMe\":true}')", + "Bash(python -m json.tool)", + "Bash(curl -sk -b c.txt https://localhost:7443/api/admin/health)", + "PowerShell(Get-NetTCPConnection -LocalPort 7443 -State Listen -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }; \"freed\")", + "Bash(python -)", + "Bash(curl -sk https://localhost:4200/ -o /dev/null)", + "PowerShell(foreach \\($p in 7443,4200\\) { Get-NetTCPConnection -LocalPort $p -State Listen -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue } }; \"ports freed\")", + "PowerShell(Get-NetTCPConnection -LocalPort 7443,4200 -State Listen -ErrorAction SilentlyContinue)", + "Bash(sqlcmd -S \"\\(localdb\\)\\\\MSSQLLocalDB\" -d AhkWeb -Q \"SET NOCOUNT ON; SELECT Id, UserName, NormalizedUserName, LockoutEnd, AccessFailedCount, LockoutEnabled, CASE WHEN PasswordHash IS NULL THEN 'NULL' ELSE 'set' END AS Pwd FROM AspNetUsers;\" -W -s\"|\")", + "Bash(curl -sk -X POST https://localhost:7443/api/auth/login -H \"Content-Type: application/json\" -d '{\"userName\":\"admin\",\"password\":\"Admin123!\",\"rememberMe\":true}' -w \"\\\\nHTTP %{http_code}\\\\n\")", + "Bash(curl -sk -X POST https://localhost:7443/api/auth/login -H \"Content-Type: application/json\" -d '{\"userName\":\"admin\",\"password\":\"Admin123!\"}' -o /dev/null -w \"HTTP %{http_code}\\\\n\")", + "Bash(curl -sk -X POST https://localhost:7443/api/auth/login -H \"Content-Type: application/json\" -d '{\"userName\":\"admin\",\"password\":\"nope\"}' -w \"\\\\nHTTP %{http_code}\\\\n\")", + "Bash(rm -f v.txt)", + "Bash(curl -sk -c v.txt -X POST https://localhost:4200/api/auth/login -H \"Content-Type: application/json\" -d '{\"userName\":\"admin\",\"password\":\"Admin123!\",\"rememberMe\":true}' -w \"\\\\nHTTP %{http_code}\\\\n\")", + "PowerShell(foreach \\($p in 7443,4200\\) { Get-NetTCPConnection -LocalPort $p -State Listen -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue } }; Start-Sleep -Milliseconds 500; $left = Get-NetTCPConnection -LocalPort 7443,4200 -State Listen -ErrorAction SilentlyContinue; if \\($null -eq $left\\) { \"both ports free\" } else { $left | Select-Object LocalPort, OwningProcess })", + "PowerShell(Get-NetTCPConnection -LocalPort 7443,4200 -State Listen -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }; Start-Sleep -Milliseconds 500; if \\($null -eq \\(Get-NetTCPConnection -LocalPort 7443,4200 -State Listen -ErrorAction SilentlyContinue\\)\\) { \"both ports free\" })", + "Bash(grep -nE \"^[0-9.]+ [0-9.]+ [0-9.]+ [0-9.]+ \\(k|K\\)$\")", + "Bash(sort -u -t: -k2)", + "Bash(python3 -)" + ], + "additionalDirectories": [ + "\\tmp" ] + }, + "enabledPlugins": { + "frontend-design@claude-plugins-official": true, + "claude-md-management@claude-plugins-official": true, + "security-guidance@claude-plugins-official": true } } diff --git a/CLAUDE.md b/CLAUDE.md index 527a4e35..0b6ccadb 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,7 +8,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co The repo is a monorepo of independent applications, each in its own top-level directory with its own solution/module, README, and CI workflows. There is no root-level build — each app builds separately. -It is mid-transition: the **four original apps** (`github-monitor`, `grade-management`, `review-ui`, `publish-results-pr`) are the production system today, and a **new centralized portal** (`ahk-backend` + `ahk-frontend`) is being built to replace the per-course Azure deployments with a single multi-course site at `ahk.aut.bme.hu`. The portal currently exists as a validated skeleton (auth + course-scoping + codegen); the original apps' functionality has **not** been ported into it yet. When working in this repo, be clear which of the two systems a task targets. +It is mid-transition: the **four original apps** (`github-monitor`, `grade-management`, `review-ui`, `publish-results-pr`) are the production system today, and a **new centralized portal** (`ahk-backend` + `ahk-frontend`) is being built to replace the per-course Azure deployments with a single multi-course site at `ahk.aut.bme.hu`. The portal now has auth (local + BME OIDC), the full course-scoped **data model**, the domain **services**, the read endpoints (`grades`, `statuses`, CSV export), the **site administration surface** (course CRUD, per-course GitHub integration, CI callback tokens, staff, users/roles, health checks) with its Angular console, and a one-time Cosmos→MSSQL importer. Still **not** ported: the write-side entry points — the GitHub webhook receiver, `/ahk ok` chatops, and the HMAC-verified CI callback. When working in this repo, be clear which of the two systems a task targets. ## The four applications and how they connect @@ -43,14 +43,28 @@ Key integration contracts (keep these in sync when changing either side): Replaces the per-course Azure Function deployments with one site whose domain data is assigned to **Courses** (each course = what used to be a separate deployment, e.g. `viaubc01`). This is **not** multitenant isolation — it's course-scoped data with membership-based authorization. -- **ahk-backend** — ASP.NET Core **.NET 10** Web API (`Ahk.Web.sln`): `Ahk.Web.Server` (API host), `Ahk.Web.Data` (EF Core + **MSSQL**, ASP.NET Identity, migrations, dev seeder), `Ahk.Web.Server.Tests` (xUnit + Moq). +- **ahk-backend** — ASP.NET Core **.NET 10** (`Ahk.Web.sln`). Layering: `Ahk.Web.Server` (controllers/middleware/auth, thin) → `Ahk.Web.Services` (domain logic) → `Ahk.Web.Data` (EF Core + **MSSQL**, Identity, migrations, seeder, `Normalize`). `Ahk.Web.Import` is a **throwaway** Cosmos-JSON→MSSQL console importer that references Data directly and **bypasses Services** (bulk movement, not domain ops). Tests in `Ahk.Web.Server.Tests` (xUnit + Moq). +- **No repository layer** — `DbContext` is already Unit of Work + repository. The legacy Cosmos repositories exist only because Cosmos has no composable LINQ context; that reason is gone. - **ahk-frontend** — **Angular 21** SPA (standalone components + signals). API clients/DTOs under `src/app/api/` are **NSwag-generated** from the backend's OpenAPI doc — never hand-edit them. Design decisions (rationale in the architecture plan and `ahk-backend/README.md`): -- **Auth**: cookie-based ASP.NET Identity (returns 401/403, never redirects) + a **generic OIDC** external provider (config `Authentication:Oidc:*`; disabled when empty). Deliberately **not** `MapIdentityApi` (no OIDC support, bearer-token focus, fixed shapes). +- **Auth**: cookie-based ASP.NET Identity (returns 401/403, never redirects) + an **OIDC** external provider (config `Authentication:Oidc:*`; disabled when empty). Deliberately **not** `MapIdentityApi` (no OIDC support, bearer-token focus, fixed shapes). +- **OIDC provider is BME's Shibboleth IdP** (`https://idp.bme.hu`, client `AUTAhkClient`). Non-obvious constraints, all encoded in `OidcOptions` defaults — do not "fix" them back: + - Request **exactly** the registered scopes (`openid email userinfo`). `profile` is **not** registered; asking for it gets the request rejected. + - **PKCE off** — the IdP does not advertise `code_challenge_methods_supported`. We are a confidential client (`client_secret_post`), so PKCE is defence-in-depth only. + - **`ResponseMode = query`** — ASP.NET's `form_post` default makes the callback a cross-site POST, which drops the correlation cookie under `SameSite=Lax` ("Correlation failed"). + - **No `end_session_endpoint`** is advertised, so logout is local-only; `POST /api/auth/logout` returns `{endSessionUrl}` (null today) and the SPA navigates there if set. + - `OpenIdConnectOptions` ships **only `DeleteClaim` actions** — claims arriving from the *userinfo* endpoint (BME sends `email`, `name`, `neptun_code`, `eduperson_scoped_affiliation` there) are silently dropped unless explicitly mapped in `Program.cs`. + - Persisted onto `ApplicationUser`: `NeptunCode` and `Affiliation` (multi-valued, joined with `;`), re-synced on every login by `Auth/ExternalClaimsMapper.cs`. + - The client secret is never in config — `dotnet user-secrets` locally, `Authentication__Oidc__ClientSecret` in production. +- **Dev mock OIDC provider** (`Ahk.Web.Server/MockOidc/`): only the production redirect URI is registered with BME, so localhost cannot use the real IdP. Enabled by `Authentication:Oidc:UseMockProvider` in Development; serves discovery/authorize/token/userinfo/JWKS at `/mock-oidc` and issues **genuinely signed** RS256 id_tokens so the real validation path runs. Switch persona with `GET /mock-oidc/persona?user=instructor|student|noclaims`. - **Course scoping**: path segment `/api/{course}/...`; `CourseResolutionMiddleware` resolves the `Course` and an `ICurrentCourseProvider` drives an EF Core global query filter over `ICourseScoped` entities; the `CourseMember` authorization policy gates access. Host/admin routes live under `/api/admin/...`. Machine-to-machine endpoints (webhooks / CI callbacks, added during the port) will resolve their course from the payload/token, **not** the path segment. +- **Site admins can open any course.** `CourseMembershipAuthorizationHandler` grants `CourseMember` to the `Admin` role, so `GET /api/auth/me` lists *every* course for an admin (flagged `viaSiteAdmin` where there is no membership row). The SPA's switcher and `courseGuard` read that one list and need no admin special case — keep it that way rather than branching on `isAdmin()` in new screens. +- **Admin API credential rule**: stored secrets are never returned (only `has*` flags plus a last-four hint). On update, each credential field means: `null` = leave alone, `""` = clear, anything else = replace. That is what makes saving an untouched form safe. +- **Course health checks** (`Ahk.Web.Services/Health/`): each is an `ICourseHealthCheck` registered in DI and discovered by `CourseHealthService`, so adding one is a class plus a registration line — controller and UI unchanged. Three today: webhook settings (local), GitHub access token (real call to api.github.com, 10s timeout), CI callback token. Checks must not throw; return a `Failed` result instead, or one unreachable course takes the whole dashboard down. A course's status is the worst of its checks. - **Dev**: both run HTTPS. The Angular dev proxy (`proxy.conf.js`) forwards `/api/*` to the backend so calls are **same-origin — no CORS**, and `API_BASE_URL` is provided as `''` so generated clients issue relative requests. Press F5 with the **"Full stack (backend + frontend)"** compound in `.vscode/launch.json` to start both. -- `CourseProbe` controller + `CourseNote` entity are throwaway scoping probes, removed when real course endpoints land in the port. +- **Domain model** (`Ahk.Web.Data/Entities`): `Course` 1:1 `CourseGitHubConfig` (per-course GitHub App creds + `WorkflowRunThreshold` — was per-deployment `AHK_*` — plus `GitHubAccessToken`, a PAT used for REST calls that need no installation token, today only the health check); `Student`/`Submission` replace the neptun/repo-name strings; `SubmissionEvent` (TPH: Repository/Branch/PullRequest/WorkflowRun) and `GradeRecord`+`GradeExercisePoint` are **append-only** — current state is projected, never updated. `CourseWebhookToken.Token` is globally unique because the CI callback carries no `{course}` segment. +- ⚠️ **The course query filter matches nothing when no course is resolved.** `ICurrentCourseProvider` is set by whichever entry point resolved the course. Anything without HTTP course context — dev seeder, importer, services — must use `IgnoreQueryFilters()` and filter on `courseId` itself, or it silently reads **zero rows**. Service methods therefore always take an explicit `int courseId` and never read the provider. ## Build, test, run @@ -87,7 +101,15 @@ dotnet run --project Ahk.Web.Server --launch-profile https # https://localhost:7 dotnet ef database update --project Ahk.Web.Data --startup-project Ahk.Web.Data dotnet ef migrations add --project Ahk.Web.Data --startup-project Ahk.Web.Data --output-dir Migrations ``` -Needs MSSQL (LocalDB by default; `ConnectionStrings:Default` in `appsettings.Development.json`). The dev seeder (Development env only) creates `admin`/`Admin123!` (site admin), `instructor`/`Instructor123!` (member of `viaubc01` only), and sample courses `viaubc01`, `viaubb01`. +Needs MSSQL (LocalDB by default; `ConnectionStrings:Default` in `appsettings.Development.json`). The dev seeder (Development env only) creates `admin`/`Admin123!` (site admin), `instructor`/`Instructor123!` (member of `viaubc01` only), courses `viaubc01`/`viaubb01` with GitHub config + CI token, and sample students/submissions/events/grades. The two courses are deliberately configured differently so the admin health dashboard shows a mix of states. + +⚠️ **The seeder is create-if-missing.** Editing seeded values changes nothing on a dev database that already has those rows — delete the course (or the database) to see the new values. + +```bash +# one-time Cosmos-export import (throwaway tool; delete once every course is migrated) +dotnet run --project Ahk.Web.Import -- --course --connection "" \ + --grades grades.json --events events.json --tokens tokens.json # --repo-prefix, --force +``` ### ahk-frontend (Angular 21) ```bash @@ -100,6 +122,17 @@ npm run generate-api # regenerate src/app/api from the backend's OpenAPI (back ``` `nswag.json` pins `"runtime": "Net100"` (the default Net90 binary needs .NET 9, which is not installed here). +### Portal gotchas +- **A running server locks its binary** — `dotnet build` fails with MSB3027; stop it first. `pkill -f` is unreliable here; free ports with PowerShell `Get-NetTCPConnection -LocalPort 7443 -State Listen | ... Stop-Process -Force`. +- **Never hand-delete a migration file** — the model snapshot stays advanced and the next `migrations add` scaffolds an empty diff. Use `dotnet ef migrations remove`, or delete the whole `Migrations/` dir and regenerate. +- **SQL Server rejects multiple cascade paths**: `Course`→`Student`→`Submission` alongside `Course`→`Submission` forces the `Student` FKs to `DeleteBehavior.NoAction`. Consequence: **deleting a course cannot rely on the database alone.** `CoursesAdminController.Delete` removes grade points, grades, events and submissions explicitly with `ExecuteDeleteAsync` before the course row goes — a new course-scoped entity whose FK is `NoAction` must be added to that list, or the delete fails on a foreign-key violation. +- **`sqlcmd` needs `SET QUOTED_IDENTIFIER ON`** before DML on `AspNetUsers`/`SubmissionEvents` — the filtered unique index on `GitHubDeliveryId` makes the default fail. +- **Auth cookies are named `ahk.auth` / `ahk.auth.external`, not the framework defaults** (`Program.ApplicationCookieName`). Browsers scope cookies by host and **ignore the port**, so on `localhost` every ASP.NET Identity app shares `.AspNetCore.Identity.Application`. A cookie from another project whose user id is a GUID reaches this int-keyed app and throws `"… is not a valid value for Int32"` inside `SecurityStampValidator` — a 500 on *every* request, including login. `OnValidatePrincipal` also wraps the stamp validator so an unreadable cookie signs the caller out instead of throwing. Do not revert either to the defaults. +- **Windows PowerShell 5.1 cannot load .NET 10 assemblies** (`Add-Type` throws); to find a type's namespace, `grep -ao` the DLL instead. +- **No Docker in this environment** — dev dependencies are built in-app (e.g. the mock OIDC provider), not containerized. +- **Verify UI changes by screenshotting the running app**, not by trusting the build. Chrome is at `/c/Program Files/Google/Chrome/Application/chrome.exe`. A plain `--headless=new --screenshot` fires before Angular hydrates and yields a near-empty page — add `--virtual-time-budget=4000`. For screens behind login, start Chrome with `--remote-debugging-port=9222` and drive the DevTools protocol from a Node script: Node 24 ships a built-in `WebSocket`, so this needs no npm dependency. Always pass `--ignore-certificate-errors` (self-signed dev cert). +- **No image tooling** — no PIL, no ImageMagick. To read a PNG's pixels (sampling a brand colour, checking dimensions) decode it by hand with `zlib` + `struct`. EPS files are text-ish: `%%CMYKCustomColor` in the header carries the print colour spec. + ### CI `.github/workflows/*-build.yaml` build+test each app (path-filtered so only the changed app runs). `*-azure-publish.yaml` / `*-docker-publish.yaml` deploy. Several azure-publish workflows are per-instance (e.g. `VIAUBC01`, `viaubb01`) — deployments are duplicated per course/organization instance. @@ -122,3 +155,9 @@ npm run generate-api # regenerate src/app/api from the backend's OpenAPI (back - **Style is enforced at build time**: StyleCop.Analyzers + `EnforceCodeStyleInBuild` + `AnalysisMode=AllEnabledByDefault`, and grade-management/review-ui set `TreatWarningsAsErrors=true`. A large root `.editorconfig` defines the rules — match existing style exactly or the build fails. Match idiom per project (e.g. github-monitor uses explicit namespaces; review-ui uses `ImplicitUsings`/`Nullable` enabled). - **result.txt evaluation format** (produced by evaluators, parsed by publish-results-pr): lines of `###ahk#taskname#result#comment`, with optional `group@` prefix on taskname for grouped totals. Full spec in `publish-results-pr/README.md`. - **Portal conventions differ from the original apps**: ahk-backend uses standard ASP.NET config (`appsettings*.json` — `ConnectionStrings:Default`, `Authentication:Oidc:*`), **not** `AHK_` env vars, and uses the default .NET 10 SDK analyzers (no `TreatWarningsAsErrors`), so it is not bound by the root `.editorconfig`'s StyleCop rules. ahk-frontend follows the Angular style (2-space, standalone components + signals). +- **Portal UI**: the design system lives in `ahk-frontend/src/styles.scss` — tokens plus the shared classes (`page`, `card`, `field`, `btn`, `table.data`, `badge`, `notice`, `dot`). Component stylesheets are Angular-scoped, so compose from those classes instead of restyling buttons/tables per screen. Enums cross the wire as **names** (`JsonStringEnumConverter` in `Program.cs`), which is why NSwag emits string-literal unions like `CourseRole = 'Instructor' | 'Admin'`. +- **Portal look is the BME AUT identity**, derived from aut.bme.hu — crimson Georgia headings, Verdana body, parchment (`#dbd9c0`) table headers, the department logo. Type does three jobs: `--font-display` (Georgia) for headings, `--font-ui` (Verdana) for labels/controls, `--font-mono` for machine identifiers (slugs, orgs, repos, Neptun codes, tokens) — do not "unify" them. `--brand` (`#a4001e`, headings + primary actions), `--link` (`#074371` navy, navigation) and `--bad` (`#801b1b`, broken) are **three deliberately different reds**; collapsing them loses meaning. The logo masters and every colour's provenance live in `ahk-frontend/brand/` (BME AUT identity pack + the eduID login logo); the web copies the app loads are in `ahk-frontend/public/`. No square favicon exists yet (the mark is 2.86:1); a follow-up needs a square crop from the EPS. The **login screen leads with eduID** (the federated `/api/auth/external/challenge` flow); local username/password is collapsed behind an "I don't have an eduID account" link. The eduID button follows the [eduID brand](https://eduid.hu/hu/depo/) but renders its own English "Login" rather than the official Hungarian-label PNG; `--eduid` blue is scoped to that button, never in the global palette. +- **Portal code style**: **no top-level statements** (`Program` is an explicit class with `Main`); **`int` keys everywhere**, including Identity (`IdentityUser`); the domain term is **Course**, never "tenant". +- **Frontend API errors**: use `readApiError(err, fallback)` from `ahk-frontend/src/app/core/api-error.ts` instead of parsing a `SwaggerException` inline. It pulls out the API's own `{error}`/`{errors}` message and reports status 0 as "the server is not responding" — without that, a generated-client failure surfaces as a misleading domain error (a stopped backend once looked exactly like "wrong password"). +- **Portal tests**: course-scoping is tested against `ApplicationDbContext` directly with EF InMemory + a mutable `ICurrentCourseProvider` double. `WebApplicationFactory` DbContext swaps must remove **both** `DbContextOptions` and EF 9+'s `IDbContextOptionsConfiguration` descriptors, else two providers register. `Ahk.Web.Services` exposes internals via `InternalsVisibleTo`. Frontend single run: `npx ng test --watch=false`. +- **Legacy parity is a hard constraint when porting**: grade semantics (append-only, positional `ex0`/`ex1` name carry-forward, per-exercise summing) and the CSV layout are covered by parity tests — changing them changes existing courses' grades. One deliberate deviation: `CsvExporter` sorts columns `Ordinal` rather than culture-sensitively. diff --git a/ahk-backend/Ahk.Web.Data/ApplicationDbContext.cs b/ahk-backend/Ahk.Web.Data/ApplicationDbContext.cs index 0b4d740c..2a89dd61 100644 --- a/ahk-backend/Ahk.Web.Data/ApplicationDbContext.cs +++ b/ahk-backend/Ahk.Web.Data/ApplicationDbContext.cs @@ -5,10 +5,15 @@ namespace Ahk.Web.Data; /// -/// EF Core context backing ASP.NET Identity plus the course model. Applies a global query filter on every -/// entity so a request only sees rows for the resolved current course. +/// EF Core context backing ASP.NET Identity plus the course-scoped domain model. Applies a global query filter +/// on every entity so a request only sees rows for the resolved current course. +/// +/// Note: the filter follows , which is populated by whichever entry point +/// resolved the course (route segment, webhook payload, or CI token). When no course is resolved the filter +/// matches nothing — callers with no course context (e.g. the one-time importer) must set a provider or use +/// IgnoreQueryFilters(). /// -public class ApplicationDbContext : IdentityDbContext +public class ApplicationDbContext : IdentityDbContext { private readonly ICurrentCourseProvider currentCourse; @@ -20,19 +25,60 @@ public ApplicationDbContext(DbContextOptions options, ICur public DbSet Courses => Set(); + public DbSet CourseGitHubConfigs => Set(); + public DbSet CourseMemberships => Set(); - public DbSet CourseNotes => Set(); + public DbSet CourseWebhookTokens => Set(); + + public DbSet Students => Set(); + + public DbSet Submissions => Set(); + + public DbSet SubmissionEvents => Set(); + + public DbSet GradeRecords => Set(); + + public DbSet GradeExercisePoints => Set(); protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); + builder.Entity(e => + { + e.Property(u => u.DisplayName).HasMaxLength(256); + e.Property(u => u.NeptunCode).HasMaxLength(32); + e.Property(u => u.Affiliation).HasMaxLength(256); + + // Not unique: directory accounts may have no neptun code, and it is a lookup key, not an identity. + e.HasIndex(u => u.NeptunCode); + }); + builder.Entity(e => { e.HasIndex(c => c.Slug).IsUnique(); e.Property(c => c.Slug).HasMaxLength(64).IsRequired(); e.Property(c => c.Name).HasMaxLength(256).IsRequired(); + e.Property(c => c.GitHubOrganization).HasMaxLength(256); + e.Property(c => c.RepoNamePrefix).HasMaxLength(256); + + // Machine-to-machine course resolution: organization first, then repo-name prefix. + e.HasIndex(c => c.GitHubOrganization); + e.HasIndex(c => c.RepoNamePrefix); + + e.HasOne(c => c.GitHubConfig) + .WithOne(g => g.Course!) + .HasForeignKey(g => g.CourseId) + .OnDelete(DeleteBehavior.Cascade); + }); + + builder.Entity(e => + { + e.HasIndex(g => g.CourseId).IsUnique(); + e.Property(g => g.GitHubAppId).HasMaxLength(64); + e.Property(g => g.GitHubAccessToken).HasMaxLength(512); + e.Property(g => g.GitHubWebhookSecret).HasMaxLength(512); }); builder.Entity(e => @@ -42,12 +88,98 @@ protected override void OnModelCreating(ModelBuilder builder) e.HasOne(m => m.Course).WithMany(c => c.Memberships).HasForeignKey(m => m.CourseId).OnDelete(DeleteBehavior.Cascade); }); - builder.Entity(e => + builder.Entity(e => + { + e.Property(t => t.Token).HasMaxLength(128).IsRequired(); + e.Property(t => t.Secret).HasMaxLength(512).IsRequired(); + e.Property(t => t.Description).HasMaxLength(512); + + // Globally unique: the CI callback carries no {course} segment, so the token resolves the course. + e.HasIndex(t => t.Token).IsUnique(); + e.HasOne(t => t.Course).WithMany().HasForeignKey(t => t.CourseId).OnDelete(DeleteBehavior.Cascade); + e.HasQueryFilter(t => t.CourseId == this.currentCourse.CurrentCourseId); + }); + + builder.Entity(e => + { + e.Property(s => s.Neptun).HasMaxLength(32).IsRequired(); + e.Property(s => s.GitHubUsername).HasMaxLength(128); + e.Property(s => s.Name).HasMaxLength(256); + + e.HasIndex(s => new { s.CourseId, s.Neptun }).IsUnique(); + e.HasOne(s => s.Course).WithMany().HasForeignKey(s => s.CourseId).OnDelete(DeleteBehavior.Cascade); + e.HasQueryFilter(s => s.CourseId == this.currentCourse.CurrentCourseId); + }); + + builder.Entity(e => + { + e.Property(s => s.GitHubRepoName).HasMaxLength(400).IsRequired(); + + e.HasIndex(s => new { s.CourseId, s.GitHubRepoName }).IsUnique(); + e.HasIndex(s => new { s.CourseId, s.StudentId }); + + e.HasOne(s => s.Course).WithMany().HasForeignKey(s => s.CourseId).OnDelete(DeleteBehavior.Cascade); + + // NoAction (not SetNull): Course cascades to both Student and Submission, and SQL Server rejects + // the resulting multiple cascade paths. Deleting a course still removes both. + e.HasOne(s => s.Student).WithMany(st => st!.Submissions).HasForeignKey(s => s.StudentId).OnDelete(DeleteBehavior.NoAction); + e.HasQueryFilter(s => s.CourseId == this.currentCourse.CurrentCourseId); + }); + + builder.Entity(e => + { + // Table-per-hierarchy, mirroring the original polymorphic event log. + e.HasDiscriminator("EventType") + .HasValue(nameof(RepositoryCreatedEvent)) + .HasValue(nameof(BranchCreatedEvent)) + .HasValue(nameof(PullRequestEvent)) + .HasValue(nameof(WorkflowRunEvent)); + + e.Property(x => x.GitHubDeliveryId).HasMaxLength(128); + + e.HasIndex(x => new { x.CourseId, x.SubmissionId, x.Timestamp }); + + // Filtered unique index: redelivered webhooks must not duplicate events. + e.HasIndex(x => x.GitHubDeliveryId).IsUnique().HasFilter("[GitHubDeliveryId] IS NOT NULL"); + + e.HasOne(x => x.Course).WithMany().HasForeignKey(x => x.CourseId).OnDelete(DeleteBehavior.NoAction); + e.HasOne(x => x.Submission).WithMany(s => s!.Events).HasForeignKey(x => x.SubmissionId).OnDelete(DeleteBehavior.Cascade); + e.HasQueryFilter(x => x.CourseId == this.currentCourse.CurrentCourseId); + }); + + builder.Entity(e => e.Property(x => x.Branch).HasMaxLength(400)); + builder.Entity(e => e.Property(x => x.Conclusion).HasMaxLength(64)); + builder.Entity(e => + { + e.Property(x => x.Action).HasMaxLength(64); + e.Property(x => x.HtmlUrl).HasMaxLength(1024); + e.Property(x => x.Neptun).HasMaxLength(32); + e.PrimitiveCollection(x => x.Assignees); // JSON column + }); + + builder.Entity(e => + { + e.Property(g => g.Neptun).HasMaxLength(32).IsRequired(); + e.Property(g => g.PrUrl).HasMaxLength(1024); + e.Property(g => g.Actor).HasMaxLength(256); + e.Property(g => g.Origin).HasMaxLength(1024); + + // "Latest result for this submission/PR" — the GetLastResultOf access path. + e.HasIndex(g => new { g.CourseId, g.SubmissionId, g.PrNumber, g.Date }); + + // Confirmed-grade listing and CSV export. + e.HasIndex(g => new { g.CourseId, g.Confirmed, g.Date }); + + e.HasOne(g => g.Course).WithMany().HasForeignKey(g => g.CourseId).OnDelete(DeleteBehavior.NoAction); + e.HasOne(g => g.Submission).WithMany(s => s!.Grades).HasForeignKey(g => g.SubmissionId).OnDelete(DeleteBehavior.Cascade); + e.HasOne(g => g.Student).WithMany().HasForeignKey(g => g.StudentId).OnDelete(DeleteBehavior.NoAction); + e.HasQueryFilter(g => g.CourseId == this.currentCourse.CurrentCourseId); + }); + + builder.Entity(e => { - e.Property(n => n.Text).HasMaxLength(1024).IsRequired(); - e.HasOne(n => n.Course).WithMany().HasForeignKey(n => n.CourseId).OnDelete(DeleteBehavior.Cascade); - // Course-scoping filter: only rows for the request's current course are visible. - e.HasQueryFilter(n => n.CourseId == this.currentCourse.CurrentCourseId); + e.Property(p => p.Name).HasMaxLength(256).IsRequired(); + e.HasOne(p => p.GradeRecord).WithMany(g => g!.Points).HasForeignKey(p => p.GradeRecordId).OnDelete(DeleteBehavior.Cascade); }); } } diff --git a/ahk-backend/Ahk.Web.Data/Entities/ApplicationRole.cs b/ahk-backend/Ahk.Web.Data/Entities/ApplicationRole.cs index 15ab8e88..223f9d3b 100644 --- a/ahk-backend/Ahk.Web.Data/Entities/ApplicationRole.cs +++ b/ahk-backend/Ahk.Web.Data/Entities/ApplicationRole.cs @@ -3,7 +3,7 @@ namespace Ahk.Web.Data.Entities; /// Application-wide (site-level) role, e.g. the super-admin role. Course-level roles live on . -public class ApplicationRole : IdentityRole +public class ApplicationRole : IdentityRole { public ApplicationRole() { diff --git a/ahk-backend/Ahk.Web.Data/Entities/ApplicationUser.cs b/ahk-backend/Ahk.Web.Data/Entities/ApplicationUser.cs index 49f130f9..2b8f8b12 100644 --- a/ahk-backend/Ahk.Web.Data/Entities/ApplicationUser.cs +++ b/ahk-backend/Ahk.Web.Data/Entities/ApplicationUser.cs @@ -6,9 +6,22 @@ namespace Ahk.Web.Data.Entities; /// Application user. Extends the ASP.NET Identity user with app-specific profile fields. /// A user may be a member of many s via . /// -public class ApplicationUser : IdentityUser +public class ApplicationUser : IdentityUser { public string? DisplayName { get; set; } + /// + /// Neptun code from the IdP's neptun_code claim. Not unique here (a directory account may exist + /// without one), but it is the key of the domain model, so storing it allows linking a signed-in user to + /// their rows later. + /// + public string? NeptunCode { get; set; } + + /// + /// The IdP's eduperson_scoped_affiliation claim (e.g. "staff@bme.hu"). Multi-valued at the source; + /// all values are stored joined with ';'. Kept so login can be restricted by affiliation later. + /// + public string? Affiliation { get; set; } + public ICollection CourseMemberships { get; } = new List(); } diff --git a/ahk-backend/Ahk.Web.Data/Entities/Course.cs b/ahk-backend/Ahk.Web.Data/Entities/Course.cs index a679d955..1d77a67b 100644 --- a/ahk-backend/Ahk.Web.Data/Entities/Course.cs +++ b/ahk-backend/Ahk.Web.Data/Entities/Course.cs @@ -8,7 +8,7 @@ namespace Ahk.Web.Data.Entities; /// public class Course { - public Guid Id { get; set; } = Guid.NewGuid(); + public int Id { get; set; } /// URL-safe unique identifier used in the path segment: ahk.aut.bme.hu/{Slug}/... public string Slug { get; set; } = string.Empty; @@ -17,10 +17,21 @@ public class Course public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; - // --- Placeholders for the GitHub-environment config ported from the per-course Azure deployments. --- - // Populated in the porting milestone (GitHub App id/private key, webhook secret, queue/connection - // settings, etc.). Kept nullable so the skeleton runs before the port. + // --- Repository routing --- + // These two live on Course (not CourseGitHubConfig) because machine-to-machine entry points resolve + // the course from them, and CourseResolutionMiddleware loads Course on every course-scoped request. + // Credentials deliberately live in CourseGitHubConfig so they are not on that hot path. + + /// GitHub organization owning this course's repositories — the primary resolution key. public string? GitHubOrganization { get; set; } + /// + /// Optional repository-name prefix, used to disambiguate when one organization hosts several courses. + /// This is the explicit form of what used to be the implicit "repo prefix = course" convention. + /// + public string? RepoNamePrefix { get; set; } + + public CourseGitHubConfig? GitHubConfig { get; set; } + public ICollection Memberships { get; } = new List(); } diff --git a/ahk-backend/Ahk.Web.Data/Entities/CourseGitHubConfig.cs b/ahk-backend/Ahk.Web.Data/Entities/CourseGitHubConfig.cs new file mode 100644 index 00000000..89db783f --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Entities/CourseGitHubConfig.cs @@ -0,0 +1,39 @@ +namespace Ahk.Web.Data.Entities; + +/// +/// Per-course GitHub integration configuration — what used to be the per-deployment AHK_* environment +/// variables of github-monitor (GitHubMonitorConfig.cs). Kept in its own table (1:1 with +/// ) so the per-request course lookup never loads the GitHub App private key. +/// +public class CourseGitHubConfig +{ + public int Id { get; set; } + + public int CourseId { get; set; } + + public Course? Course { get; set; } + + /// GitHub App id (was AHK_GitHubAppId). + public string? GitHubAppId { get; set; } + + /// GitHub App private key (was AHK_GitHubAppPrivateKey). Stored as a plain column by decision. + public string? GitHubAppPrivateKey { get; set; } + + /// + /// Personal / fine-grained access token used for REST calls that do not need a per-installation token — + /// today only the connectivity health check. Stored as a plain column, like the other credentials. + /// + public string? GitHubAccessToken { get; set; } + + /// Secret used to validate the X-Hub-Signature-256 webhook signature (was AHK_GitHubWebhookSecret). + public string? GitHubWebhookSecret { get; set; } + + /// Maximum allowed Actions workflow runs per repository; was the const WorkflowRunThreshold = 5. + public int WorkflowRunThreshold { get; set; } = 5; + + /// When false, incoming webhooks for this course are ignored. + public bool Enabled { get; set; } = true; + + /// Last time an administrator changed these settings; shown in the admin UI. + public DateTimeOffset? UpdatedAt { get; set; } +} diff --git a/ahk-backend/Ahk.Web.Data/Entities/CourseMembership.cs b/ahk-backend/Ahk.Web.Data/Entities/CourseMembership.cs index 75541128..5abc1af6 100644 --- a/ahk-backend/Ahk.Web.Data/Entities/CourseMembership.cs +++ b/ahk-backend/Ahk.Web.Data/Entities/CourseMembership.cs @@ -3,9 +3,9 @@ namespace Ahk.Web.Data.Entities; /// Assigns a user to a course with a course-level role. A user may belong to many courses. public class CourseMembership { - public string UserId { get; set; } = string.Empty; + public int UserId { get; set; } - public Guid CourseId { get; set; } + public int CourseId { get; set; } public CourseRole Role { get; set; } = CourseRole.Instructor; diff --git a/ahk-backend/Ahk.Web.Data/Entities/CourseNote.cs b/ahk-backend/Ahk.Web.Data/Entities/CourseNote.cs deleted file mode 100644 index 5fc1577b..00000000 --- a/ahk-backend/Ahk.Web.Data/Entities/CourseNote.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Ahk.Web.Data.Entities; - -/// -/// Temporary probe entity used only to verify course-scoping end-to-end in this skeleton milestone. -/// It is the first type; real domain entities (grades, statuses, submissions) -/// replace it during the port, and this type is then removed. -/// -public class CourseNote : ICourseScoped -{ - public Guid Id { get; set; } = Guid.NewGuid(); - - public Guid CourseId { get; set; } - - public string Text { get; set; } = string.Empty; - - public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; - - public Course? Course { get; set; } -} diff --git a/ahk-backend/Ahk.Web.Data/Entities/CourseWebhookToken.cs b/ahk-backend/Ahk.Web.Data/Entities/CourseWebhookToken.cs new file mode 100644 index 00000000..c9164527 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Entities/CourseWebhookToken.cs @@ -0,0 +1,31 @@ +namespace Ahk.Web.Data.Entities; + +/// +/// Token/secret pair authenticating a course's CI callbacks (publish-results-pr → evaluation-result webhook). +/// Relational form of the webhooktokens container's WebhookToken. +/// +/// is globally unique because the CI callback carries no {course} path segment — the token +/// itself is how that request resolves to a course. is the HMAC-SHA256 key, verified with +/// the scheme ported from grade-management/.../Helpers/HmacSha256Validator.cs. +/// +public class CourseWebhookToken : ICourseScoped +{ + public int Id { get; set; } + + public int CourseId { get; set; } + + public Course? Course { get; set; } + + /// Public identifier sent in the X-Ahk-Token header. + public string Token { get; set; } = string.Empty; + + /// HMAC signing key. Stored as a plain column by decision. + public string Secret { get; set; } = string.Empty; + + public string? Description { get; set; } + + public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; + + /// When set, the token is no longer accepted. + public DateTimeOffset? RevokedAt { get; set; } +} diff --git a/ahk-backend/Ahk.Web.Data/Entities/GradeRecord.cs b/ahk-backend/Ahk.Web.Data/Entities/GradeRecord.cs new file mode 100644 index 00000000..3f4292c3 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Entities/GradeRecord.cs @@ -0,0 +1,67 @@ +namespace Ahk.Web.Data.Entities; + +/// +/// Append-only grade result — the relational form of StudentResult. Never updated: every evaluation +/// or teacher action inserts a new row, and the current grade is the latest one. +/// distinguishes an automated evaluation result (false) from a teacher-approved grade (true). +/// +public class GradeRecord : ICourseScoped +{ + public int Id { get; set; } + + public int CourseId { get; set; } + + public Course? Course { get; set; } + + public int SubmissionId { get; set; } + + public Submission? Submission { get; set; } + + public int? StudentId { get; set; } + + public Student? Student { get; set; } + + /// + /// Neptun as recorded at grading time. Denormalized deliberately: the CSV export reports the code that was + /// on the result, and a grade is a point-in-time record. + /// + public string Neptun { get; set; } = string.Empty; + + public int? PrNumber { get; set; } + + public string? PrUrl { get; set; } + + public DateTimeOffset Date { get; set; } + + /// Who produced it: a teacher's GitHub login, or "grade-management-api" for automated results. + public string? Actor { get; set; } + + /// Where it came from: the commit URL for automated results, or the PR comment for chatops. + public string? Origin { get; set; } + + /// False for automated evaluation results; true once a teacher approves/overrides via /ahk ok. + public bool Confirmed { get; set; } + + public ICollection Points { get; } = new List(); +} + +/// +/// Points for one exercise of a — the relational form of the embedded +/// ExerciseWithPoint collection. Exercise names stay free-form (positional "ex0"/"ex1" carried forward +/// from the previous result, or the evaluator's exerciseName), matching the original semantics. +/// +public class GradeExercisePoint +{ + public int Id { get; set; } + + public int GradeRecordId { get; set; } + + public GradeRecord? GradeRecord { get; set; } + + public string Name { get; set; } = string.Empty; + + public double Point { get; set; } + + /// Preserves positional order, which is significant for the /ahk ok "5 3.5 0" chatops form. + public int Order { get; set; } +} diff --git a/ahk-backend/Ahk.Web.Data/Entities/ICourseScoped.cs b/ahk-backend/Ahk.Web.Data/Entities/ICourseScoped.cs index 904b323f..428d8569 100644 --- a/ahk-backend/Ahk.Web.Data/Entities/ICourseScoped.cs +++ b/ahk-backend/Ahk.Web.Data/Entities/ICourseScoped.cs @@ -7,5 +7,5 @@ namespace Ahk.Web.Data.Entities; /// public interface ICourseScoped { - Guid CourseId { get; } + int CourseId { get; } } diff --git a/ahk-backend/Ahk.Web.Data/Entities/Student.cs b/ahk-backend/Ahk.Web.Data/Entities/Student.cs new file mode 100644 index 00000000..1a9c8056 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Entities/Student.cs @@ -0,0 +1,27 @@ +namespace Ahk.Web.Data.Entities; + +/// +/// A student within a course, keyed by Neptun code (BME's student identifier). Replaces the neptun string +/// that was denormalized onto every grade and pull-request event in the original system. +/// Rows are created on first sighting (from neptun.txt or a pull-request payload); no roster import +/// is required. +/// +public class Student : ICourseScoped +{ + public int Id { get; set; } + + public int CourseId { get; set; } + + public Course? Course { get; set; } + + /// Normalized with (uppercase, trimmed). + public string Neptun { get; set; } = string.Empty; + + public string? GitHubUsername { get; set; } + + public string? Name { get; set; } + + public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; + + public ICollection Submissions { get; } = new List(); +} diff --git a/ahk-backend/Ahk.Web.Data/Entities/Submission.cs b/ahk-backend/Ahk.Web.Data/Entities/Submission.cs new file mode 100644 index 00000000..af24c162 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Entities/Submission.cs @@ -0,0 +1,34 @@ +namespace Ahk.Web.Data.Entities; + +/// +/// One student's GitHub repository within a course — the anchor that status events and grades hang off. +/// Replaces the raw repository-name string that the original system used as its grouping key +/// (StudentResult.GitHubRepoName / StatusEventBase.Repository). +/// +public class Submission : ICourseScoped +{ + public int Id { get; set; } + + public int CourseId { get; set; } + + public Course? Course { get; set; } + + /// Null while the student is unknown — the repository often exists before neptun.txt is pushed. + public int? StudentId { get; set; } + + public Student? Student { get; set; } + + /// Full "owner/name", normalized with (lowercase, trimmed). + public string GitHubRepoName { get; set; } = string.Empty; + + /// GitHub's numeric repository id, when known. + public long? GitHubRepoId { get; set; } + + public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; + + public DateTimeOffset? LastEventAt { get; set; } + + public ICollection Events { get; } = new List(); + + public ICollection Grades { get; } = new List(); +} diff --git a/ahk-backend/Ahk.Web.Data/Entities/SubmissionEvent.cs b/ahk-backend/Ahk.Web.Data/Entities/SubmissionEvent.cs new file mode 100644 index 00000000..d5e7c72e --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Entities/SubmissionEvent.cs @@ -0,0 +1,64 @@ +namespace Ahk.Web.Data.Entities; + +/// +/// Append-only status event for a submission. Mirrors the polymorphic StatusEventBase log of the +/// original CosmosDB events container, mapped table-per-hierarchy. Rows are never mutated; the +/// current status of a submission is a projection over this log (see the status projection in +/// Ahk.Web.Services), exactly as StatusTrackingService.createStatus did. +/// +public abstract class SubmissionEvent : ICourseScoped +{ + public int Id { get; set; } + + public int CourseId { get; set; } + + public Course? Course { get; set; } + + public int SubmissionId { get; set; } + + public Submission? Submission { get; set; } + + public DateTimeOffset Timestamp { get; set; } + + /// + /// GitHub's X-GitHub-Delivery id. Unique (where present) so webhook redeliveries do not duplicate rows — + /// a guard the original Cosmos model lacked. + /// + public string? GitHubDeliveryId { get; set; } +} + +/// Repository was created for the student (was RepositoryCreateEvent). +public class RepositoryCreatedEvent : SubmissionEvent +{ +} + +/// A branch was pushed/created (was BranchCreateEvent). +public class BranchCreatedEvent : SubmissionEvent +{ + public string Branch { get; set; } = string.Empty; +} + +/// Pull request activity (was PullRequestEvent). +public class PullRequestEvent : SubmissionEvent +{ + public int Number { get; set; } + + /// GitHub action name (opened, closed, assigned, ...); the latest one is the PR's status. + public string Action { get; set; } = string.Empty; + + public string? HtmlUrl { get; set; } + + /// Neptun as seen at event time; kept as a snapshot because the original log recorded it per event. + public string? Neptun { get; set; } + + /// Assignees at event time. Mapped to a JSON column — only ever concatenated for display. + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "EF Core primitive collections require a settable List.")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1002:Do not expose generic lists", Justification = "EF Core primitive collections require List.")] + public List Assignees { get; set; } = new(); +} + +/// An Actions workflow run finished (was WorkflowRunEvent). +public class WorkflowRunEvent : SubmissionEvent +{ + public string? Conclusion { get; set; } +} diff --git a/ahk-backend/Ahk.Web.Data/ICurrentCourseProvider.cs b/ahk-backend/Ahk.Web.Data/ICurrentCourseProvider.cs index b38a3ddf..71867e81 100644 --- a/ahk-backend/Ahk.Web.Data/ICurrentCourseProvider.cs +++ b/ahk-backend/Ahk.Web.Data/ICurrentCourseProvider.cs @@ -6,11 +6,11 @@ namespace Ahk.Web.Data; /// public interface ICurrentCourseProvider { - Guid? CurrentCourseId { get; } + int? CurrentCourseId { get; } } /// No-op provider (no active course). Used at design time and in host/admin contexts. public sealed class NullCurrentCourseProvider : ICurrentCourseProvider { - public Guid? CurrentCourseId => null; + public int? CurrentCourseId => null; } diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260720133652_InitialCreate.Designer.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260720133652_InitialCreate.Designer.cs deleted file mode 100644 index 367e5c68..00000000 --- a/ahk-backend/Ahk.Web.Data/Migrations/20260720133652_InitialCreate.Designer.cs +++ /dev/null @@ -1,394 +0,0 @@ -// -using System; -using Ahk.Web.Data; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -#nullable disable - -namespace Ahk.Web.Data.Migrations -{ - [DbContext(typeof(ApplicationDbContext))] - [Migration("20260720133652_InitialCreate")] - partial class InitialCreate - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.10") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationRole", b => - { - b.Property("Id") - .HasColumnType("nvarchar(450)"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("nvarchar(max)"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex") - .HasFilter("[NormalizedName] IS NOT NULL"); - - b.ToTable("AspNetRoles", (string)null); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => - { - b.Property("Id") - .HasColumnType("nvarchar(450)"); - - b.Property("AccessFailedCount") - .HasColumnType("int"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("nvarchar(max)"); - - b.Property("DisplayName") - .HasColumnType("nvarchar(max)"); - - b.Property("Email") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("EmailConfirmed") - .HasColumnType("bit"); - - b.Property("LockoutEnabled") - .HasColumnType("bit"); - - b.Property("LockoutEnd") - .HasColumnType("datetimeoffset"); - - b.Property("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("PasswordHash") - .HasColumnType("nvarchar(max)"); - - b.Property("PhoneNumber") - .HasColumnType("nvarchar(max)"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("bit"); - - b.Property("SecurityStamp") - .HasColumnType("nvarchar(max)"); - - b.Property("TwoFactorEnabled") - .HasColumnType("bit"); - - b.Property("UserName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasDatabaseName("UserNameIndex") - .HasFilter("[NormalizedUserName] IS NOT NULL"); - - b.ToTable("AspNetUsers", (string)null); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("CreatedAt") - .HasColumnType("datetimeoffset"); - - b.Property("GitHubOrganization") - .HasColumnType("nvarchar(max)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Slug") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("Id"); - - b.HasIndex("Slug") - .IsUnique(); - - b.ToTable("Courses"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => - { - b.Property("UserId") - .HasColumnType("nvarchar(450)"); - - b.Property("CourseId") - .HasColumnType("uniqueidentifier"); - - b.Property("Role") - .HasColumnType("int"); - - b.HasKey("UserId", "CourseId"); - - b.HasIndex("CourseId"); - - b.ToTable("CourseMemberships"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseNote", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("CourseId") - .HasColumnType("uniqueidentifier"); - - b.Property("CreatedAt") - .HasColumnType("datetimeoffset"); - - b.Property("Text") - .IsRequired() - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.HasKey("Id"); - - b.HasIndex("CourseId"); - - b.ToTable("CourseNotes"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("nvarchar(max)"); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(max)"); - - b.Property("RoleId") - .IsRequired() - .HasColumnType("nvarchar(450)"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("nvarchar(max)"); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(max)"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("nvarchar(450)"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("nvarchar(450)"); - - b.Property("ProviderKey") - .HasColumnType("nvarchar(450)"); - - b.Property("ProviderDisplayName") - .HasColumnType("nvarchar(max)"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("nvarchar(450)"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("nvarchar(450)"); - - b.Property("RoleId") - .HasColumnType("nvarchar(450)"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("nvarchar(450)"); - - b.Property("LoginProvider") - .HasColumnType("nvarchar(450)"); - - b.Property("Name") - .HasColumnType("nvarchar(450)"); - - b.Property("Value") - .HasColumnType("nvarchar(max)"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens", (string)null); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithMany("Memberships") - .HasForeignKey("CourseId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", "User") - .WithMany("CourseMemberships") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Course"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseNote", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithMany() - .HasForeignKey("CourseId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Course"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => - { - b.Navigation("CourseMemberships"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => - { - b.Navigation("Memberships"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260720133652_InitialCreate.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260720133652_InitialCreate.cs deleted file mode 100644 index 1b891886..00000000 --- a/ahk-backend/Ahk.Web.Data/Migrations/20260720133652_InitialCreate.cs +++ /dev/null @@ -1,310 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Ahk.Web.Data.Migrations -{ - /// - public partial class InitialCreate : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "AspNetRoles", - columns: table => new - { - Id = table.Column(type: "nvarchar(450)", nullable: false), - Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - NormalizedName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetRoles", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "AspNetUsers", - columns: table => new - { - Id = table.Column(type: "nvarchar(450)", nullable: false), - DisplayName = table.Column(type: "nvarchar(max)", nullable: true), - UserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - NormalizedUserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - Email = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - NormalizedEmail = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), - EmailConfirmed = table.Column(type: "bit", nullable: false), - PasswordHash = table.Column(type: "nvarchar(max)", nullable: true), - SecurityStamp = table.Column(type: "nvarchar(max)", nullable: true), - ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true), - PhoneNumber = table.Column(type: "nvarchar(max)", nullable: true), - PhoneNumberConfirmed = table.Column(type: "bit", nullable: false), - TwoFactorEnabled = table.Column(type: "bit", nullable: false), - LockoutEnd = table.Column(type: "datetimeoffset", nullable: true), - LockoutEnabled = table.Column(type: "bit", nullable: false), - AccessFailedCount = table.Column(type: "int", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUsers", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Courses", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - Slug = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), - Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - CreatedAt = table.Column(type: "datetimeoffset", nullable: false), - GitHubOrganization = table.Column(type: "nvarchar(max)", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Courses", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "AspNetRoleClaims", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - RoleId = table.Column(type: "nvarchar(450)", nullable: false), - ClaimType = table.Column(type: "nvarchar(max)", nullable: true), - ClaimValue = table.Column(type: "nvarchar(max)", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); - table.ForeignKey( - name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", - column: x => x.RoleId, - principalTable: "AspNetRoles", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserClaims", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - UserId = table.Column(type: "nvarchar(450)", nullable: false), - ClaimType = table.Column(type: "nvarchar(max)", nullable: true), - ClaimValue = table.Column(type: "nvarchar(max)", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); - table.ForeignKey( - name: "FK_AspNetUserClaims_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserLogins", - columns: table => new - { - LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), - ProviderKey = table.Column(type: "nvarchar(450)", nullable: false), - ProviderDisplayName = table.Column(type: "nvarchar(max)", nullable: true), - UserId = table.Column(type: "nvarchar(450)", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); - table.ForeignKey( - name: "FK_AspNetUserLogins_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserRoles", - columns: table => new - { - UserId = table.Column(type: "nvarchar(450)", nullable: false), - RoleId = table.Column(type: "nvarchar(450)", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); - table.ForeignKey( - name: "FK_AspNetUserRoles_AspNetRoles_RoleId", - column: x => x.RoleId, - principalTable: "AspNetRoles", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_AspNetUserRoles_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserTokens", - columns: table => new - { - UserId = table.Column(type: "nvarchar(450)", nullable: false), - LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), - Name = table.Column(type: "nvarchar(450)", nullable: false), - Value = table.Column(type: "nvarchar(max)", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); - table.ForeignKey( - name: "FK_AspNetUserTokens_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "CourseMemberships", - columns: table => new - { - UserId = table.Column(type: "nvarchar(450)", nullable: false), - CourseId = table.Column(type: "uniqueidentifier", nullable: false), - Role = table.Column(type: "int", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_CourseMemberships", x => new { x.UserId, x.CourseId }); - table.ForeignKey( - name: "FK_CourseMemberships_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_CourseMemberships_Courses_CourseId", - column: x => x.CourseId, - principalTable: "Courses", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "CourseNotes", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - CourseId = table.Column(type: "uniqueidentifier", nullable: false), - Text = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: false), - CreatedAt = table.Column(type: "datetimeoffset", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_CourseNotes", x => x.Id); - table.ForeignKey( - name: "FK_CourseNotes_Courses_CourseId", - column: x => x.CourseId, - principalTable: "Courses", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_AspNetRoleClaims_RoleId", - table: "AspNetRoleClaims", - column: "RoleId"); - - migrationBuilder.CreateIndex( - name: "RoleNameIndex", - table: "AspNetRoles", - column: "NormalizedName", - unique: true, - filter: "[NormalizedName] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_AspNetUserClaims_UserId", - table: "AspNetUserClaims", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_AspNetUserLogins_UserId", - table: "AspNetUserLogins", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_AspNetUserRoles_RoleId", - table: "AspNetUserRoles", - column: "RoleId"); - - migrationBuilder.CreateIndex( - name: "EmailIndex", - table: "AspNetUsers", - column: "NormalizedEmail"); - - migrationBuilder.CreateIndex( - name: "UserNameIndex", - table: "AspNetUsers", - column: "NormalizedUserName", - unique: true, - filter: "[NormalizedUserName] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_CourseMemberships_CourseId", - table: "CourseMemberships", - column: "CourseId"); - - migrationBuilder.CreateIndex( - name: "IX_CourseNotes_CourseId", - table: "CourseNotes", - column: "CourseId"); - - migrationBuilder.CreateIndex( - name: "IX_Courses_Slug", - table: "Courses", - column: "Slug", - unique: true); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "AspNetRoleClaims"); - - migrationBuilder.DropTable( - name: "AspNetUserClaims"); - - migrationBuilder.DropTable( - name: "AspNetUserLogins"); - - migrationBuilder.DropTable( - name: "AspNetUserRoles"); - - migrationBuilder.DropTable( - name: "AspNetUserTokens"); - - migrationBuilder.DropTable( - name: "CourseMemberships"); - - migrationBuilder.DropTable( - name: "CourseNotes"); - - migrationBuilder.DropTable( - name: "AspNetRoles"); - - migrationBuilder.DropTable( - name: "AspNetUsers"); - - migrationBuilder.DropTable( - name: "Courses"); - } - } -} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260721170210_InitialCreate.Designer.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260721170210_InitialCreate.Designer.cs new file mode 100644 index 00000000..60835431 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Migrations/20260721170210_InitialCreate.Designer.cs @@ -0,0 +1,836 @@ +// +using System; +using Ahk.Web.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Ahk.Web.Data.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20260721170210_InitialCreate")] + partial class InitialCreate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("GitHubOrganization") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("RepoNamePrefix") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("GitHubOrganization"); + + b.HasIndex("RepoNamePrefix"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseGitHubConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("GitHubAppId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("GitHubAppPrivateKey") + .HasColumnType("nvarchar(max)"); + + b.Property("GitHubWebhookSecret") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("WorkflowRunThreshold") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CourseId") + .IsUnique(); + + b.ToTable("CourseGitHubConfigs"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("Role") + .HasColumnType("int"); + + b.HasKey("UserId", "CourseId"); + + b.HasIndex("CourseId"); + + b.ToTable("CourseMemberships"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseWebhookToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("Description") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("RevokedAt") + .HasColumnType("datetimeoffset"); + + b.Property("Secret") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("Token") + .IsUnique(); + + b.ToTable("CourseWebhookTokens"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeExercisePoint", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("GradeRecordId") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("Point") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("GradeRecordId"); + + b.ToTable("GradeExercisePoints"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Actor") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Confirmed") + .HasColumnType("bit"); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("Date") + .HasColumnType("datetimeoffset"); + + b.Property("Neptun") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("Origin") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("PrNumber") + .HasColumnType("int"); + + b.Property("PrUrl") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("StudentId") + .HasColumnType("int"); + + b.Property("SubmissionId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("StudentId"); + + b.HasIndex("SubmissionId"); + + b.HasIndex("CourseId", "Confirmed", "Date"); + + b.HasIndex("CourseId", "SubmissionId", "PrNumber", "Date"); + + b.ToTable("GradeRecords"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("GitHubUsername") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Neptun") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.HasKey("Id"); + + b.HasIndex("CourseId", "Neptun") + .IsUnique(); + + b.ToTable("Students"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("GitHubRepoId") + .HasColumnType("bigint"); + + b.Property("GitHubRepoName") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("LastEventAt") + .HasColumnType("datetimeoffset"); + + b.Property("StudentId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("StudentId"); + + b.HasIndex("CourseId", "GitHubRepoName") + .IsUnique(); + + b.HasIndex("CourseId", "StudentId"); + + b.ToTable("Submissions"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.SubmissionEvent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("EventType") + .IsRequired() + .HasMaxLength(34) + .HasColumnType("nvarchar(34)"); + + b.Property("GitHubDeliveryId") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SubmissionId") + .HasColumnType("int"); + + b.Property("Timestamp") + .HasColumnType("datetimeoffset"); + + b.HasKey("Id"); + + b.HasIndex("GitHubDeliveryId") + .IsUnique() + .HasFilter("[GitHubDeliveryId] IS NOT NULL"); + + b.HasIndex("SubmissionId"); + + b.HasIndex("CourseId", "SubmissionId", "Timestamp"); + + b.ToTable("SubmissionEvents"); + + b.HasDiscriminator("EventType").HasValue("SubmissionEvent"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.BranchCreatedEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.Property("Branch") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.HasDiscriminator().HasValue("BranchCreatedEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.PullRequestEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.Property("Action") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.PrimitiveCollection("Assignees") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("HtmlUrl") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("Neptun") + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("Number") + .HasColumnType("int"); + + b.HasDiscriminator().HasValue("PullRequestEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.RepositoryCreatedEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.HasDiscriminator().HasValue("RepositoryCreatedEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.WorkflowRunEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.Property("Conclusion") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasDiscriminator().HasValue("WorkflowRunEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseGitHubConfig", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithOne("GitHubConfig") + .HasForeignKey("Ahk.Web.Data.Entities.CourseGitHubConfig", "CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany("Memberships") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", "User") + .WithMany("CourseMemberships") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseWebhookToken", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeExercisePoint", b => + { + b.HasOne("Ahk.Web.Data.Entities.GradeRecord", "GradeRecord") + .WithMany("Points") + .HasForeignKey("GradeRecordId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GradeRecord"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Student", "Student") + .WithMany() + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("Ahk.Web.Data.Entities.Submission", "Submission") + .WithMany("Grades") + .HasForeignKey("SubmissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + + b.Navigation("Student"); + + b.Navigation("Submission"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Student", "Student") + .WithMany("Submissions") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("Course"); + + b.Navigation("Student"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.SubmissionEvent", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Submission", "Submission") + .WithMany("Events") + .HasForeignKey("SubmissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + + b.Navigation("Submission"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => + { + b.Navigation("CourseMemberships"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => + { + b.Navigation("GitHubConfig"); + + b.Navigation("Memberships"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => + { + b.Navigation("Points"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => + { + b.Navigation("Submissions"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => + { + b.Navigation("Events"); + + b.Navigation("Grades"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260721170210_InitialCreate.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260721170210_InitialCreate.cs new file mode 100644 index 00000000..8bfee552 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Migrations/20260721170210_InitialCreate.cs @@ -0,0 +1,593 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ahk.Web.Data.Migrations +{ + /// + public partial class InitialCreate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AspNetRoles", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + NormalizedName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetUsers", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + DisplayName = table.Column(type: "nvarchar(max)", nullable: true), + UserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + NormalizedUserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + Email = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + NormalizedEmail = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + EmailConfirmed = table.Column(type: "bit", nullable: false), + PasswordHash = table.Column(type: "nvarchar(max)", nullable: true), + SecurityStamp = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true), + PhoneNumber = table.Column(type: "nvarchar(max)", nullable: true), + PhoneNumberConfirmed = table.Column(type: "bit", nullable: false), + TwoFactorEnabled = table.Column(type: "bit", nullable: false), + LockoutEnd = table.Column(type: "datetimeoffset", nullable: true), + LockoutEnabled = table.Column(type: "bit", nullable: false), + AccessFailedCount = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUsers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Courses", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Slug = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + CreatedAt = table.Column(type: "datetimeoffset", nullable: false), + GitHubOrganization = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + RepoNamePrefix = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Courses", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetRoleClaims", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + RoleId = table.Column(type: "int", nullable: false), + ClaimType = table.Column(type: "nvarchar(max)", nullable: true), + ClaimValue = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserClaims", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + UserId = table.Column(type: "int", nullable: false), + ClaimType = table.Column(type: "nvarchar(max)", nullable: true), + ClaimValue = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetUserClaims_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserLogins", + columns: table => new + { + LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), + ProviderKey = table.Column(type: "nvarchar(450)", nullable: false), + ProviderDisplayName = table.Column(type: "nvarchar(max)", nullable: true), + UserId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_AspNetUserLogins_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserRoles", + columns: table => new + { + UserId = table.Column(type: "int", nullable: false), + RoleId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserTokens", + columns: table => new + { + UserId = table.Column(type: "int", nullable: false), + LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), + Name = table.Column(type: "nvarchar(450)", nullable: false), + Value = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_AspNetUserTokens_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "CourseGitHubConfigs", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + CourseId = table.Column(type: "int", nullable: false), + GitHubAppId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + GitHubAppPrivateKey = table.Column(type: "nvarchar(max)", nullable: true), + GitHubWebhookSecret = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), + WorkflowRunThreshold = table.Column(type: "int", nullable: false), + Enabled = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CourseGitHubConfigs", x => x.Id); + table.ForeignKey( + name: "FK_CourseGitHubConfigs_Courses_CourseId", + column: x => x.CourseId, + principalTable: "Courses", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "CourseMemberships", + columns: table => new + { + UserId = table.Column(type: "int", nullable: false), + CourseId = table.Column(type: "int", nullable: false), + Role = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CourseMemberships", x => new { x.UserId, x.CourseId }); + table.ForeignKey( + name: "FK_CourseMemberships_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_CourseMemberships_Courses_CourseId", + column: x => x.CourseId, + principalTable: "Courses", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "CourseWebhookTokens", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + CourseId = table.Column(type: "int", nullable: false), + Token = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + Secret = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: false), + Description = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), + CreatedAt = table.Column(type: "datetimeoffset", nullable: false), + RevokedAt = table.Column(type: "datetimeoffset", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_CourseWebhookTokens", x => x.Id); + table.ForeignKey( + name: "FK_CourseWebhookTokens_Courses_CourseId", + column: x => x.CourseId, + principalTable: "Courses", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Students", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + CourseId = table.Column(type: "int", nullable: false), + Neptun = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), + GitHubUsername = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), + Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + CreatedAt = table.Column(type: "datetimeoffset", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Students", x => x.Id); + table.ForeignKey( + name: "FK_Students_Courses_CourseId", + column: x => x.CourseId, + principalTable: "Courses", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Submissions", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + CourseId = table.Column(type: "int", nullable: false), + StudentId = table.Column(type: "int", nullable: true), + GitHubRepoName = table.Column(type: "nvarchar(400)", maxLength: 400, nullable: false), + GitHubRepoId = table.Column(type: "bigint", nullable: true), + CreatedAt = table.Column(type: "datetimeoffset", nullable: false), + LastEventAt = table.Column(type: "datetimeoffset", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Submissions", x => x.Id); + table.ForeignKey( + name: "FK_Submissions_Courses_CourseId", + column: x => x.CourseId, + principalTable: "Courses", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Submissions_Students_StudentId", + column: x => x.StudentId, + principalTable: "Students", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "GradeRecords", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + CourseId = table.Column(type: "int", nullable: false), + SubmissionId = table.Column(type: "int", nullable: false), + StudentId = table.Column(type: "int", nullable: true), + Neptun = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: false), + PrNumber = table.Column(type: "int", nullable: true), + PrUrl = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true), + Date = table.Column(type: "datetimeoffset", nullable: false), + Actor = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + Origin = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true), + Confirmed = table.Column(type: "bit", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_GradeRecords", x => x.Id); + table.ForeignKey( + name: "FK_GradeRecords_Courses_CourseId", + column: x => x.CourseId, + principalTable: "Courses", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_GradeRecords_Students_StudentId", + column: x => x.StudentId, + principalTable: "Students", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_GradeRecords_Submissions_SubmissionId", + column: x => x.SubmissionId, + principalTable: "Submissions", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "SubmissionEvents", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + CourseId = table.Column(type: "int", nullable: false), + SubmissionId = table.Column(type: "int", nullable: false), + Timestamp = table.Column(type: "datetimeoffset", nullable: false), + GitHubDeliveryId = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), + EventType = table.Column(type: "nvarchar(34)", maxLength: 34, nullable: false), + Branch = table.Column(type: "nvarchar(400)", maxLength: 400, nullable: true), + Number = table.Column(type: "int", nullable: true), + Action = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), + HtmlUrl = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true), + Neptun = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: true), + Assignees = table.Column(type: "nvarchar(max)", nullable: true), + Conclusion = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_SubmissionEvents", x => x.Id); + table.ForeignKey( + name: "FK_SubmissionEvents_Courses_CourseId", + column: x => x.CourseId, + principalTable: "Courses", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_SubmissionEvents_Submissions_SubmissionId", + column: x => x.SubmissionId, + principalTable: "Submissions", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "GradeExercisePoints", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + GradeRecordId = table.Column(type: "int", nullable: false), + Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Point = table.Column(type: "float", nullable: false), + Order = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_GradeExercisePoints", x => x.Id); + table.ForeignKey( + name: "FK_GradeExercisePoints_GradeRecords_GradeRecordId", + column: x => x.GradeRecordId, + principalTable: "GradeRecords", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_AspNetRoleClaims_RoleId", + table: "AspNetRoleClaims", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "RoleNameIndex", + table: "AspNetRoles", + column: "NormalizedName", + unique: true, + filter: "[NormalizedName] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserClaims_UserId", + table: "AspNetUserClaims", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserLogins_UserId", + table: "AspNetUserLogins", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserRoles_RoleId", + table: "AspNetUserRoles", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "AspNetUsers", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "AspNetUsers", + column: "NormalizedUserName", + unique: true, + filter: "[NormalizedUserName] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_CourseGitHubConfigs_CourseId", + table: "CourseGitHubConfigs", + column: "CourseId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_CourseMemberships_CourseId", + table: "CourseMemberships", + column: "CourseId"); + + migrationBuilder.CreateIndex( + name: "IX_Courses_GitHubOrganization", + table: "Courses", + column: "GitHubOrganization"); + + migrationBuilder.CreateIndex( + name: "IX_Courses_RepoNamePrefix", + table: "Courses", + column: "RepoNamePrefix"); + + migrationBuilder.CreateIndex( + name: "IX_Courses_Slug", + table: "Courses", + column: "Slug", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_CourseWebhookTokens_CourseId", + table: "CourseWebhookTokens", + column: "CourseId"); + + migrationBuilder.CreateIndex( + name: "IX_CourseWebhookTokens_Token", + table: "CourseWebhookTokens", + column: "Token", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_GradeExercisePoints_GradeRecordId", + table: "GradeExercisePoints", + column: "GradeRecordId"); + + migrationBuilder.CreateIndex( + name: "IX_GradeRecords_CourseId_Confirmed_Date", + table: "GradeRecords", + columns: new[] { "CourseId", "Confirmed", "Date" }); + + migrationBuilder.CreateIndex( + name: "IX_GradeRecords_CourseId_SubmissionId_PrNumber_Date", + table: "GradeRecords", + columns: new[] { "CourseId", "SubmissionId", "PrNumber", "Date" }); + + migrationBuilder.CreateIndex( + name: "IX_GradeRecords_StudentId", + table: "GradeRecords", + column: "StudentId"); + + migrationBuilder.CreateIndex( + name: "IX_GradeRecords_SubmissionId", + table: "GradeRecords", + column: "SubmissionId"); + + migrationBuilder.CreateIndex( + name: "IX_Students_CourseId_Neptun", + table: "Students", + columns: new[] { "CourseId", "Neptun" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_SubmissionEvents_CourseId_SubmissionId_Timestamp", + table: "SubmissionEvents", + columns: new[] { "CourseId", "SubmissionId", "Timestamp" }); + + migrationBuilder.CreateIndex( + name: "IX_SubmissionEvents_GitHubDeliveryId", + table: "SubmissionEvents", + column: "GitHubDeliveryId", + unique: true, + filter: "[GitHubDeliveryId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_SubmissionEvents_SubmissionId", + table: "SubmissionEvents", + column: "SubmissionId"); + + migrationBuilder.CreateIndex( + name: "IX_Submissions_CourseId_GitHubRepoName", + table: "Submissions", + columns: new[] { "CourseId", "GitHubRepoName" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Submissions_CourseId_StudentId", + table: "Submissions", + columns: new[] { "CourseId", "StudentId" }); + + migrationBuilder.CreateIndex( + name: "IX_Submissions_StudentId", + table: "Submissions", + column: "StudentId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AspNetRoleClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserLogins"); + + migrationBuilder.DropTable( + name: "AspNetUserRoles"); + + migrationBuilder.DropTable( + name: "AspNetUserTokens"); + + migrationBuilder.DropTable( + name: "CourseGitHubConfigs"); + + migrationBuilder.DropTable( + name: "CourseMemberships"); + + migrationBuilder.DropTable( + name: "CourseWebhookTokens"); + + migrationBuilder.DropTable( + name: "GradeExercisePoints"); + + migrationBuilder.DropTable( + name: "SubmissionEvents"); + + migrationBuilder.DropTable( + name: "AspNetRoles"); + + migrationBuilder.DropTable( + name: "AspNetUsers"); + + migrationBuilder.DropTable( + name: "GradeRecords"); + + migrationBuilder.DropTable( + name: "Submissions"); + + migrationBuilder.DropTable( + name: "Students"); + + migrationBuilder.DropTable( + name: "Courses"); + } + } +} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260722162506_OidcUserClaims.Designer.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260722162506_OidcUserClaims.Designer.cs new file mode 100644 index 00000000..2035a568 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Migrations/20260722162506_OidcUserClaims.Designer.cs @@ -0,0 +1,847 @@ +// +using System; +using Ahk.Web.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Ahk.Web.Data.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20260722162506_OidcUserClaims")] + partial class OidcUserClaims + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("Affiliation") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NeptunCode") + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NeptunCode"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("GitHubOrganization") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("RepoNamePrefix") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("GitHubOrganization"); + + b.HasIndex("RepoNamePrefix"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseGitHubConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("GitHubAppId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("GitHubAppPrivateKey") + .HasColumnType("nvarchar(max)"); + + b.Property("GitHubWebhookSecret") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("WorkflowRunThreshold") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CourseId") + .IsUnique(); + + b.ToTable("CourseGitHubConfigs"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("Role") + .HasColumnType("int"); + + b.HasKey("UserId", "CourseId"); + + b.HasIndex("CourseId"); + + b.ToTable("CourseMemberships"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseWebhookToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("Description") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("RevokedAt") + .HasColumnType("datetimeoffset"); + + b.Property("Secret") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("Token") + .IsUnique(); + + b.ToTable("CourseWebhookTokens"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeExercisePoint", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("GradeRecordId") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("Point") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("GradeRecordId"); + + b.ToTable("GradeExercisePoints"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Actor") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Confirmed") + .HasColumnType("bit"); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("Date") + .HasColumnType("datetimeoffset"); + + b.Property("Neptun") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("Origin") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("PrNumber") + .HasColumnType("int"); + + b.Property("PrUrl") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("StudentId") + .HasColumnType("int"); + + b.Property("SubmissionId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("StudentId"); + + b.HasIndex("SubmissionId"); + + b.HasIndex("CourseId", "Confirmed", "Date"); + + b.HasIndex("CourseId", "SubmissionId", "PrNumber", "Date"); + + b.ToTable("GradeRecords"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("GitHubUsername") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Neptun") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.HasKey("Id"); + + b.HasIndex("CourseId", "Neptun") + .IsUnique(); + + b.ToTable("Students"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("GitHubRepoId") + .HasColumnType("bigint"); + + b.Property("GitHubRepoName") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("LastEventAt") + .HasColumnType("datetimeoffset"); + + b.Property("StudentId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("StudentId"); + + b.HasIndex("CourseId", "GitHubRepoName") + .IsUnique(); + + b.HasIndex("CourseId", "StudentId"); + + b.ToTable("Submissions"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.SubmissionEvent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("EventType") + .IsRequired() + .HasMaxLength(34) + .HasColumnType("nvarchar(34)"); + + b.Property("GitHubDeliveryId") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SubmissionId") + .HasColumnType("int"); + + b.Property("Timestamp") + .HasColumnType("datetimeoffset"); + + b.HasKey("Id"); + + b.HasIndex("GitHubDeliveryId") + .IsUnique() + .HasFilter("[GitHubDeliveryId] IS NOT NULL"); + + b.HasIndex("SubmissionId"); + + b.HasIndex("CourseId", "SubmissionId", "Timestamp"); + + b.ToTable("SubmissionEvents"); + + b.HasDiscriminator("EventType").HasValue("SubmissionEvent"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.BranchCreatedEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.Property("Branch") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.HasDiscriminator().HasValue("BranchCreatedEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.PullRequestEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.Property("Action") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.PrimitiveCollection("Assignees") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("HtmlUrl") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("Neptun") + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("Number") + .HasColumnType("int"); + + b.HasDiscriminator().HasValue("PullRequestEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.RepositoryCreatedEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.HasDiscriminator().HasValue("RepositoryCreatedEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.WorkflowRunEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.Property("Conclusion") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasDiscriminator().HasValue("WorkflowRunEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseGitHubConfig", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithOne("GitHubConfig") + .HasForeignKey("Ahk.Web.Data.Entities.CourseGitHubConfig", "CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany("Memberships") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", "User") + .WithMany("CourseMemberships") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseWebhookToken", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeExercisePoint", b => + { + b.HasOne("Ahk.Web.Data.Entities.GradeRecord", "GradeRecord") + .WithMany("Points") + .HasForeignKey("GradeRecordId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GradeRecord"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Student", "Student") + .WithMany() + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("Ahk.Web.Data.Entities.Submission", "Submission") + .WithMany("Grades") + .HasForeignKey("SubmissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + + b.Navigation("Student"); + + b.Navigation("Submission"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Student", "Student") + .WithMany("Submissions") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("Course"); + + b.Navigation("Student"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.SubmissionEvent", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Submission", "Submission") + .WithMany("Events") + .HasForeignKey("SubmissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + + b.Navigation("Submission"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => + { + b.Navigation("CourseMemberships"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => + { + b.Navigation("GitHubConfig"); + + b.Navigation("Memberships"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => + { + b.Navigation("Points"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => + { + b.Navigation("Submissions"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => + { + b.Navigation("Events"); + + b.Navigation("Grades"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260722162506_OidcUserClaims.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260722162506_OidcUserClaims.cs new file mode 100644 index 00000000..53b675e6 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Migrations/20260722162506_OidcUserClaims.cs @@ -0,0 +1,69 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ahk.Web.Data.Migrations +{ + /// + public partial class OidcUserClaims : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "DisplayName", + table: "AspNetUsers", + type: "nvarchar(256)", + maxLength: 256, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AddColumn( + name: "Affiliation", + table: "AspNetUsers", + type: "nvarchar(256)", + maxLength: 256, + nullable: true); + + migrationBuilder.AddColumn( + name: "NeptunCode", + table: "AspNetUsers", + type: "nvarchar(32)", + maxLength: 32, + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUsers_NeptunCode", + table: "AspNetUsers", + column: "NeptunCode"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_AspNetUsers_NeptunCode", + table: "AspNetUsers"); + + migrationBuilder.DropColumn( + name: "Affiliation", + table: "AspNetUsers"); + + migrationBuilder.DropColumn( + name: "NeptunCode", + table: "AspNetUsers"); + + migrationBuilder.AlterColumn( + name: "DisplayName", + table: "AspNetUsers", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(256)", + oldMaxLength: 256, + oldNullable: true); + } + } +} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260723112811_GitHubAccessToken.Designer.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260723112811_GitHubAccessToken.Designer.cs new file mode 100644 index 00000000..d08dbebb --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Migrations/20260723112811_GitHubAccessToken.Designer.cs @@ -0,0 +1,854 @@ +// +using System; +using Ahk.Web.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Ahk.Web.Data.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20260723112811_GitHubAccessToken")] + partial class GitHubAccessToken + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("Affiliation") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NeptunCode") + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NeptunCode"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("GitHubOrganization") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("RepoNamePrefix") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("GitHubOrganization"); + + b.HasIndex("RepoNamePrefix"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseGitHubConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("GitHubAccessToken") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("GitHubAppId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("GitHubAppPrivateKey") + .HasColumnType("nvarchar(max)"); + + b.Property("GitHubWebhookSecret") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("UpdatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("WorkflowRunThreshold") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CourseId") + .IsUnique(); + + b.ToTable("CourseGitHubConfigs"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("Role") + .HasColumnType("int"); + + b.HasKey("UserId", "CourseId"); + + b.HasIndex("CourseId"); + + b.ToTable("CourseMemberships"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseWebhookToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("Description") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("RevokedAt") + .HasColumnType("datetimeoffset"); + + b.Property("Secret") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("Token") + .IsUnique(); + + b.ToTable("CourseWebhookTokens"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeExercisePoint", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("GradeRecordId") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("Point") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("GradeRecordId"); + + b.ToTable("GradeExercisePoints"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Actor") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Confirmed") + .HasColumnType("bit"); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("Date") + .HasColumnType("datetimeoffset"); + + b.Property("Neptun") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("Origin") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("PrNumber") + .HasColumnType("int"); + + b.Property("PrUrl") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("StudentId") + .HasColumnType("int"); + + b.Property("SubmissionId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("StudentId"); + + b.HasIndex("SubmissionId"); + + b.HasIndex("CourseId", "Confirmed", "Date"); + + b.HasIndex("CourseId", "SubmissionId", "PrNumber", "Date"); + + b.ToTable("GradeRecords"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("GitHubUsername") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Neptun") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.HasKey("Id"); + + b.HasIndex("CourseId", "Neptun") + .IsUnique(); + + b.ToTable("Students"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("GitHubRepoId") + .HasColumnType("bigint"); + + b.Property("GitHubRepoName") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("LastEventAt") + .HasColumnType("datetimeoffset"); + + b.Property("StudentId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("StudentId"); + + b.HasIndex("CourseId", "GitHubRepoName") + .IsUnique(); + + b.HasIndex("CourseId", "StudentId"); + + b.ToTable("Submissions"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.SubmissionEvent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("EventType") + .IsRequired() + .HasMaxLength(34) + .HasColumnType("nvarchar(34)"); + + b.Property("GitHubDeliveryId") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SubmissionId") + .HasColumnType("int"); + + b.Property("Timestamp") + .HasColumnType("datetimeoffset"); + + b.HasKey("Id"); + + b.HasIndex("GitHubDeliveryId") + .IsUnique() + .HasFilter("[GitHubDeliveryId] IS NOT NULL"); + + b.HasIndex("SubmissionId"); + + b.HasIndex("CourseId", "SubmissionId", "Timestamp"); + + b.ToTable("SubmissionEvents"); + + b.HasDiscriminator("EventType").HasValue("SubmissionEvent"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.BranchCreatedEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.Property("Branch") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.HasDiscriminator().HasValue("BranchCreatedEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.PullRequestEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.Property("Action") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.PrimitiveCollection("Assignees") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("HtmlUrl") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("Neptun") + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("Number") + .HasColumnType("int"); + + b.HasDiscriminator().HasValue("PullRequestEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.RepositoryCreatedEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.HasDiscriminator().HasValue("RepositoryCreatedEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.WorkflowRunEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.Property("Conclusion") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasDiscriminator().HasValue("WorkflowRunEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseGitHubConfig", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithOne("GitHubConfig") + .HasForeignKey("Ahk.Web.Data.Entities.CourseGitHubConfig", "CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany("Memberships") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", "User") + .WithMany("CourseMemberships") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseWebhookToken", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeExercisePoint", b => + { + b.HasOne("Ahk.Web.Data.Entities.GradeRecord", "GradeRecord") + .WithMany("Points") + .HasForeignKey("GradeRecordId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GradeRecord"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Student", "Student") + .WithMany() + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("Ahk.Web.Data.Entities.Submission", "Submission") + .WithMany("Grades") + .HasForeignKey("SubmissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + + b.Navigation("Student"); + + b.Navigation("Submission"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Student", "Student") + .WithMany("Submissions") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("Course"); + + b.Navigation("Student"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.SubmissionEvent", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Submission", "Submission") + .WithMany("Events") + .HasForeignKey("SubmissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + + b.Navigation("Submission"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => + { + b.Navigation("CourseMemberships"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => + { + b.Navigation("GitHubConfig"); + + b.Navigation("Memberships"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => + { + b.Navigation("Points"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => + { + b.Navigation("Submissions"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => + { + b.Navigation("Events"); + + b.Navigation("Grades"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260723112811_GitHubAccessToken.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260723112811_GitHubAccessToken.cs new file mode 100644 index 00000000..59a73a6f --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Migrations/20260723112811_GitHubAccessToken.cs @@ -0,0 +1,40 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ahk.Web.Data.Migrations +{ + /// + public partial class GitHubAccessToken : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "GitHubAccessToken", + table: "CourseGitHubConfigs", + type: "nvarchar(512)", + maxLength: 512, + nullable: true); + + migrationBuilder.AddColumn( + name: "UpdatedAt", + table: "CourseGitHubConfigs", + type: "datetimeoffset", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "GitHubAccessToken", + table: "CourseGitHubConfigs"); + + migrationBuilder.DropColumn( + name: "UpdatedAt", + table: "CourseGitHubConfigs"); + } + } +} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/ApplicationDbContextModelSnapshot.cs b/ahk-backend/Ahk.Web.Data/Migrations/ApplicationDbContextModelSnapshot.cs index 90b3dd64..52915996 100644 --- a/ahk-backend/Ahk.Web.Data/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/ahk-backend/Ahk.Web.Data/Migrations/ApplicationDbContextModelSnapshot.cs @@ -24,8 +24,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationRole", b => { - b.Property("Id") - .HasColumnType("nvarchar(450)"); + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); b.Property("ConcurrencyStamp") .IsConcurrencyToken() @@ -51,18 +54,26 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => { - b.Property("Id") - .HasColumnType("nvarchar(450)"); + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); b.Property("AccessFailedCount") .HasColumnType("int"); + b.Property("Affiliation") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + b.Property("ConcurrencyStamp") .IsConcurrencyToken() .HasColumnType("nvarchar(max)"); b.Property("DisplayName") - .HasColumnType("nvarchar(max)"); + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); b.Property("Email") .HasMaxLength(256) @@ -77,6 +88,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("LockoutEnd") .HasColumnType("datetimeoffset"); + b.Property("NeptunCode") + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + b.Property("NormalizedEmail") .HasMaxLength(256) .HasColumnType("nvarchar(256)"); @@ -106,6 +121,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); + b.HasIndex("NeptunCode"); + b.HasIndex("NormalizedEmail") .HasDatabaseName("EmailIndex"); @@ -119,21 +136,28 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => { - b.Property("Id") + b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); b.Property("CreatedAt") .HasColumnType("datetimeoffset"); b.Property("GitHubOrganization") - .HasColumnType("nvarchar(max)"); + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); b.Property("Name") .IsRequired() .HasMaxLength(256) .HasColumnType("nvarchar(256)"); + b.Property("RepoNamePrefix") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + b.Property("Slug") .IsRequired() .HasMaxLength(64) @@ -141,19 +165,66 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); + b.HasIndex("GitHubOrganization"); + + b.HasIndex("RepoNamePrefix"); + b.HasIndex("Slug") .IsUnique(); b.ToTable("Courses"); }); + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseGitHubConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("GitHubAccessToken") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("GitHubAppId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("GitHubAppPrivateKey") + .HasColumnType("nvarchar(max)"); + + b.Property("GitHubWebhookSecret") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("UpdatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("WorkflowRunThreshold") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CourseId") + .IsUnique(); + + b.ToTable("CourseGitHubConfigs"); + }); + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => { - b.Property("UserId") - .HasColumnType("nvarchar(450)"); + b.Property("UserId") + .HasColumnType("int"); - b.Property("CourseId") - .HasColumnType("uniqueidentifier"); + b.Property("CourseId") + .HasColumnType("int"); b.Property("Role") .HasColumnType("int"); @@ -165,31 +236,251 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("CourseMemberships"); }); - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseNote", b => + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseWebhookToken", b => { - b.Property("Id") + b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - b.Property("CourseId") - .HasColumnType("uniqueidentifier"); + b.Property("CourseId") + .HasColumnType("int"); b.Property("CreatedAt") .HasColumnType("datetimeoffset"); - b.Property("Text") + b.Property("Description") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("RevokedAt") + .HasColumnType("datetimeoffset"); + + b.Property("Secret") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("Token") .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("Token") + .IsUnique(); + + b.ToTable("CourseWebhookTokens"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeExercisePoint", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("GradeRecordId") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("Point") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("GradeRecordId"); + + b.ToTable("GradeExercisePoints"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Actor") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Confirmed") + .HasColumnType("bit"); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("Date") + .HasColumnType("datetimeoffset"); + + b.Property("Neptun") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("Origin") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("PrNumber") + .HasColumnType("int"); + + b.Property("PrUrl") .HasMaxLength(1024) .HasColumnType("nvarchar(1024)"); + b.Property("StudentId") + .HasColumnType("int"); + + b.Property("SubmissionId") + .HasColumnType("int"); + b.HasKey("Id"); - b.HasIndex("CourseId"); + b.HasIndex("StudentId"); + + b.HasIndex("SubmissionId"); + + b.HasIndex("CourseId", "Confirmed", "Date"); + + b.HasIndex("CourseId", "SubmissionId", "PrNumber", "Date"); + + b.ToTable("GradeRecords"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("GitHubUsername") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Neptun") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.HasKey("Id"); + + b.HasIndex("CourseId", "Neptun") + .IsUnique(); + + b.ToTable("Students"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - b.ToTable("CourseNotes"); + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("GitHubRepoId") + .HasColumnType("bigint"); + + b.Property("GitHubRepoName") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("LastEventAt") + .HasColumnType("datetimeoffset"); + + b.Property("StudentId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("StudentId"); + + b.HasIndex("CourseId", "GitHubRepoName") + .IsUnique(); + + b.HasIndex("CourseId", "StudentId"); + + b.ToTable("Submissions"); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + modelBuilder.Entity("Ahk.Web.Data.Entities.SubmissionEvent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("EventType") + .IsRequired() + .HasMaxLength(34) + .HasColumnType("nvarchar(34)"); + + b.Property("GitHubDeliveryId") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SubmissionId") + .HasColumnType("int"); + + b.Property("Timestamp") + .HasColumnType("datetimeoffset"); + + b.HasKey("Id"); + + b.HasIndex("GitHubDeliveryId") + .IsUnique() + .HasFilter("[GitHubDeliveryId] IS NOT NULL"); + + b.HasIndex("SubmissionId"); + + b.HasIndex("CourseId", "SubmissionId", "Timestamp"); + + b.ToTable("SubmissionEvents"); + + b.HasDiscriminator("EventType").HasValue("SubmissionEvent"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -203,9 +494,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("ClaimValue") .HasColumnType("nvarchar(max)"); - b.Property("RoleId") - .IsRequired() - .HasColumnType("nvarchar(450)"); + b.Property("RoleId") + .HasColumnType("int"); b.HasKey("Id"); @@ -214,7 +504,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("AspNetRoleClaims", (string)null); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -228,9 +518,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("ClaimValue") .HasColumnType("nvarchar(max)"); - b.Property("UserId") - .IsRequired() - .HasColumnType("nvarchar(450)"); + b.Property("UserId") + .HasColumnType("int"); b.HasKey("Id"); @@ -239,7 +528,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("AspNetUserClaims", (string)null); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { b.Property("LoginProvider") .HasColumnType("nvarchar(450)"); @@ -250,9 +539,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("ProviderDisplayName") .HasColumnType("nvarchar(max)"); - b.Property("UserId") - .IsRequired() - .HasColumnType("nvarchar(450)"); + b.Property("UserId") + .HasColumnType("int"); b.HasKey("LoginProvider", "ProviderKey"); @@ -261,13 +549,13 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("AspNetUserLogins", (string)null); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => { - b.Property("UserId") - .HasColumnType("nvarchar(450)"); + b.Property("UserId") + .HasColumnType("int"); - b.Property("RoleId") - .HasColumnType("nvarchar(450)"); + b.Property("RoleId") + .HasColumnType("int"); b.HasKey("UserId", "RoleId"); @@ -276,10 +564,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("AspNetUserRoles", (string)null); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => { - b.Property("UserId") - .HasColumnType("nvarchar(450)"); + b.Property("UserId") + .HasColumnType("int"); b.Property("LoginProvider") .HasColumnType("nvarchar(450)"); @@ -295,6 +583,74 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("AspNetUserTokens", (string)null); }); + modelBuilder.Entity("Ahk.Web.Data.Entities.BranchCreatedEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.Property("Branch") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.HasDiscriminator().HasValue("BranchCreatedEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.PullRequestEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.Property("Action") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.PrimitiveCollection("Assignees") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("HtmlUrl") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("Neptun") + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("Number") + .HasColumnType("int"); + + b.HasDiscriminator().HasValue("PullRequestEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.RepositoryCreatedEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.HasDiscriminator().HasValue("RepositoryCreatedEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.WorkflowRunEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.Property("Conclusion") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasDiscriminator().HasValue("WorkflowRunEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseGitHubConfig", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithOne("GitHubConfig") + .HasForeignKey("Ahk.Web.Data.Entities.CourseGitHubConfig", "CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => { b.HasOne("Ahk.Web.Data.Entities.Course", "Course") @@ -314,18 +670,103 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("User"); }); - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseNote", b => + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseWebhookToken", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeExercisePoint", b => + { + b.HasOne("Ahk.Web.Data.Entities.GradeRecord", "GradeRecord") + .WithMany("Points") + .HasForeignKey("GradeRecordId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GradeRecord"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Student", "Student") + .WithMany() + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("Ahk.Web.Data.Entities.Submission", "Submission") + .WithMany("Grades") + .HasForeignKey("SubmissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + + b.Navigation("Student"); + + b.Navigation("Submission"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Student", "Student") + .WithMany("Submissions") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("Course"); + + b.Navigation("Student"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.SubmissionEvent", b => { b.HasOne("Ahk.Web.Data.Entities.Course", "Course") .WithMany() .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Submission", "Submission") + .WithMany("Events") + .HasForeignKey("SubmissionId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.Navigation("Course"); + + b.Navigation("Submission"); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) .WithMany() @@ -334,7 +775,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .IsRequired(); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => { b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) .WithMany() @@ -343,7 +784,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .IsRequired(); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) .WithMany() @@ -352,7 +793,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .IsRequired(); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => { b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) .WithMany() @@ -367,7 +808,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .IsRequired(); }); - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => { b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) .WithMany() @@ -383,8 +824,27 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => { + b.Navigation("GitHubConfig"); + b.Navigation("Memberships"); }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => + { + b.Navigation("Points"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => + { + b.Navigation("Submissions"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => + { + b.Navigation("Events"); + + b.Navigation("Grades"); + }); #pragma warning restore 612, 618 } } diff --git a/ahk-backend/Ahk.Web.Data/Normalize.cs b/ahk-backend/Ahk.Web.Data/Normalize.cs new file mode 100644 index 00000000..90a2a261 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Normalize.cs @@ -0,0 +1,16 @@ +using System.Diagnostics.CodeAnalysis; + +namespace Ahk.Web.Data; + +/// +/// Canonical forms for the two natural keys carried over from the original system. Ported verbatim from +/// grade-management/Ahk.GradeManagement.Data/Normalize.cs so imported rows and runtime-written rows +/// are byte-identical; lookups depend on it. +/// +public static class Normalize +{ + public static string Neptun(string value) => value is null ? string.Empty : value.ToUpperInvariant().Trim(); + + [SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase", Justification = "Repo name is normalized to lowercase.")] + public static string RepoName(string value) => value is null ? string.Empty : value.ToLowerInvariant().Trim(); +} diff --git a/ahk-backend/Ahk.Web.Data/Seed/DevDataSeeder.cs b/ahk-backend/Ahk.Web.Data/Seed/DevDataSeeder.cs index a604389a..506f8437 100644 --- a/ahk-backend/Ahk.Web.Data/Seed/DevDataSeeder.cs +++ b/ahk-backend/Ahk.Web.Data/Seed/DevDataSeeder.cs @@ -6,8 +6,12 @@ namespace Ahk.Web.Data.Seed; /// -/// Seeds development data: applies migrations, ensures roles, a super-admin, two sample courses, a membership -/// in only one of them, and a probe note per course — enough to exercise auth and course-scoping locally. +/// Seeds development data: applies migrations, ensures roles, a super-admin, an instructor scoped to one +/// course, two sample courses with GitHub config + CI token, and a small amount of realistic domain data +/// (students, submissions, status events, grades) so the dashboards and exports have something to show. +/// +/// All reads use IgnoreQueryFilters(): there is no HTTP request here, so no current course is set and +/// the course query filter would otherwise match nothing. /// public static class DevDataSeeder { @@ -46,31 +50,131 @@ public static async Task SeedAsync(IServiceProvider services) await userManager.CreateAsync(instructor, "Instructor123!"); } - var seedCourses = new[] + // The two courses are deliberately configured differently so the admin health dashboard shows a mix of + // states in development: one fully wired up bar the access token, one with nothing filled in yet. + var courseA = await EnsureCourseAsync(db, "viaubc01", "Sample Course VIAUBC01", "ahk-viaubc01", webhookSecret: "dev-webhook-secret"); + await EnsureCourseAsync(db, "viaubb01", "Sample Course VIAUBB01", "ahk-viaubb01", webhookSecret: null); + + // Instructor is a member of the first course only. + var hasMembership = await db.CourseMemberships.IgnoreQueryFilters() + .AnyAsync(m => m.UserId == instructor.Id && m.CourseId == courseA.Id); + if (!hasMembership) { - new Course { Slug = "viaubc01", Name = "Sample Course VIAUBC01" }, - new Course { Slug = "viaubb01", Name = "Sample Course VIAUBB01" }, - }; + db.CourseMemberships.Add(new CourseMembership { UserId = instructor.Id, CourseId = courseA.Id, Role = CourseRole.Instructor }); + await db.SaveChangesAsync(); + } + + await EnsureSampleDomainDataAsync(db, courseA); + } + + private static async Task EnsureCourseAsync(ApplicationDbContext db, string slug, string name, string org, string? webhookSecret) + { + var course = await db.Courses.IgnoreQueryFilters().FirstOrDefaultAsync(c => c.Slug == slug); + if (course is not null) + return course; - foreach (var course in seedCourses) + course = new Course { - var existing = await db.Courses.FirstOrDefaultAsync(c => c.Slug == course.Slug); - if (existing is null) + Slug = slug, + Name = name, + GitHubOrganization = org, + RepoNamePrefix = slug, + GitHubConfig = new CourseGitHubConfig { - db.Courses.Add(course); - db.CourseNotes.Add(new CourseNote { CourseId = course.Id, Text = $"Probe note for {course.Slug}" }); - } - } + GitHubWebhookSecret = webhookSecret, + WorkflowRunThreshold = 5, + Enabled = true, + }, + }; + db.Courses.Add(course); await db.SaveChangesAsync(); - // Instructor is a member of the first course only. - var firstCourse = await db.Courses.FirstAsync(c => c.Slug == "viaubc01"); - var hasMembership = await db.CourseMemberships.AnyAsync(m => m.UserId == instructor.Id && m.CourseId == firstCourse.Id); - if (!hasMembership) + db.CourseWebhookTokens.Add(new CourseWebhookToken { - db.CourseMemberships.Add(new CourseMembership { UserId = instructor.Id, CourseId = firstCourse.Id, Role = CourseRole.Instructor }); + CourseId = course.Id, + Token = $"dev-token-{slug}", + Secret = $"dev-secret-{slug}", + Description = "Development CI callback token", + }); + await db.SaveChangesAsync(); + + return course; + } + + /// Two students with submissions, a realistic event stream, and both an automated and a confirmed grade. + private static async Task EnsureSampleDomainDataAsync(ApplicationDbContext db, Course course) + { + if (await db.Submissions.IgnoreQueryFilters().AnyAsync(s => s.CourseId == course.Id)) + return; + + var samples = new[] + { + (Neptun: "ABC123", Repo: $"{course.GitHubOrganization}/{course.Slug}-hw1-abc123", Points: new[] { 2d, 3d }, Conclusion: "success"), + (Neptun: "XYZ789", Repo: $"{course.GitHubOrganization}/{course.Slug}-hw1-xyz789", Points: new[] { 1d, 0d }, Conclusion: "failure"), + }; + + var now = DateTimeOffset.UtcNow; + + foreach (var (neptun, repo, points, conclusion) in samples) + { + var student = new Student { CourseId = course.Id, Neptun = Normalize.Neptun(neptun) }; + db.Students.Add(student); + await db.SaveChangesAsync(); + + var submission = new Submission + { + CourseId = course.Id, + StudentId = student.Id, + GitHubRepoName = Normalize.RepoName(repo), + LastEventAt = now, + }; + db.Submissions.Add(submission); + await db.SaveChangesAsync(); + + db.SubmissionEvents.AddRange( + new RepositoryCreatedEvent { CourseId = course.Id, SubmissionId = submission.Id, Timestamp = now.AddDays(-7) }, + new BranchCreatedEvent { CourseId = course.Id, SubmissionId = submission.Id, Timestamp = now.AddDays(-6), Branch = "solution" }, + new PullRequestEvent + { + CourseId = course.Id, + SubmissionId = submission.Id, + Timestamp = now.AddDays(-5), + Number = 1, + Action = "opened", + HtmlUrl = $"https://github.com/{submission.GitHubRepoName}/pull/1", + Neptun = student.Neptun, + Assignees = new List { "instructor" }, + }, + new WorkflowRunEvent { CourseId = course.Id, SubmissionId = submission.Id, Timestamp = now.AddDays(-5), Conclusion = conclusion }); + + // Automated evaluation result, then the teacher's confirmed grade (append-only history). + AddGrade(db, course, submission, student, points, confirmed: false, date: now.AddDays(-5), actor: "grade-management-api", origin: $"https://github.com/{submission.GitHubRepoName}/commit/abc1234"); + AddGrade(db, course, submission, student, points, confirmed: true, date: now.AddDays(-1), actor: "instructor", origin: $"https://github.com/{submission.GitHubRepoName}/pull/1"); + await db.SaveChangesAsync(); } } + + private static void AddGrade(ApplicationDbContext db, Course course, Submission submission, Student student, double[] points, bool confirmed, DateTimeOffset date, string actor, string origin) + { + var grade = new GradeRecord + { + CourseId = course.Id, + SubmissionId = submission.Id, + StudentId = student.Id, + Neptun = student.Neptun, + PrNumber = 1, + PrUrl = $"https://github.com/{submission.GitHubRepoName}/pull/1", + Date = date, + Actor = actor, + Origin = origin, + Confirmed = confirmed, + }; + + for (var i = 0; i < points.Length; i++) + grade.Points.Add(new GradeExercisePoint { Name = $"ex{i}", Point = points[i], Order = i }); + + db.GradeRecords.Add(grade); + } } diff --git a/ahk-backend/Ahk.Web.Import/Ahk.Web.Import.csproj b/ahk-backend/Ahk.Web.Import/Ahk.Web.Import.csproj new file mode 100644 index 00000000..fa08ba02 --- /dev/null +++ b/ahk-backend/Ahk.Web.Import/Ahk.Web.Import.csproj @@ -0,0 +1,18 @@ + + + + + + + + + + + + Exe + net10.0 + enable + enable + + + diff --git a/ahk-backend/Ahk.Web.Import/CosmosDocuments.cs b/ahk-backend/Ahk.Web.Import/CosmosDocuments.cs new file mode 100644 index 00000000..4f74ca9e --- /dev/null +++ b/ahk-backend/Ahk.Web.Import/CosmosDocuments.cs @@ -0,0 +1,91 @@ +using System.Text.Json.Serialization; + +namespace Ahk.Web.Import; + +/// +/// Shapes of the exported CosmosDB documents. Only the fields we import are declared; Cosmos system fields +/// (_rid, _self, _etag, _ts, _attachments) are simply ignored by the deserializer. +/// +internal sealed class StudentResultDocument +{ + [JsonPropertyName("id")] + public string? Id { get; set; } + + public string? Neptun { get; set; } + + public string? GitHubRepoName { get; set; } + + public int? GitHubPrNumber { get; set; } + + public string? GitHubPrUrl { get; set; } + + public DateTimeOffset Date { get; set; } + + public string? Actor { get; set; } + + public string? Origin { get; set; } + + public List? Points { get; set; } + + public bool Confirmed { get; set; } +} + +internal sealed class ExerciseWithPointDocument +{ + public string? Name { get; set; } + + public double Point { get; set; } +} + +/// +/// One document from the events container. The container is polymorphic: $type selects which +/// subtype's fields are populated (written by the legacy StatusEventItemJsonConverter). +/// +internal sealed class StatusEventDocument +{ + [JsonPropertyName("id")] + public string? Id { get; set; } + + [JsonPropertyName("$type")] + public string? Type { get; set; } + + public string? Repository { get; set; } + + public DateTimeOffset Timestamp { get; set; } + + // BranchCreateEvent + public string? Branch { get; set; } + + // WorkflowRunEvent + public string? Conclusion { get; set; } + + // PullRequestEvent + public string? Action { get; set; } + + public List? Assignees { get; set; } + + public string? Neptun { get; set; } + + public string? HtmlUrl { get; set; } + + public int Number { get; set; } +} + +internal sealed class WebhookTokenDocument +{ + [JsonPropertyName("id")] + public string? Id { get; set; } + + public string? Secret { get; set; } + + public string? Description { get; set; } +} + +/// Legacy $type discriminator values from the events container. +internal static class LegacyEventTypes +{ + public const string RepositoryCreate = "RepositoryCreateEvent"; + public const string BranchCreate = "BranchCreateEvent"; + public const string PullRequest = "PullRequestEvent"; + public const string WorkflowRun = "WorkflowRunEvent"; +} diff --git a/ahk-backend/Ahk.Web.Import/ImportOptions.cs b/ahk-backend/Ahk.Web.Import/ImportOptions.cs new file mode 100644 index 00000000..177aa550 --- /dev/null +++ b/ahk-backend/Ahk.Web.Import/ImportOptions.cs @@ -0,0 +1,70 @@ +namespace Ahk.Web.Import; + +/// Command-line options for the one-time import. +internal sealed class ImportOptions +{ + public string CourseSlug { get; private set; } = string.Empty; + + public string ConnectionString { get; private set; } = string.Empty; + + public string? GradesFile { get; private set; } + + public string? EventsFile { get; private set; } + + public string? TokensFile { get; private set; } + + /// Only import rows whose repository name starts with this prefix (when one export covers several courses). + public string? RepoPrefix { get; private set; } + + public bool Force { get; private set; } + + public static string Usage => + """ + Ahk.Web.Import — one-time CosmosDB -> MSSQL import (throwaway tool). + + --course Target course slug (must already exist). [required] + --connection Target MSSQL connection string. [required] + --grades Exported 'grades' container. + --events Exported 'events' container. + --tokens Exported 'webhooktokens' container. + --repo-prefix Only import repositories starting with this prefix. + --force Import even if the course already has domain rows. + + At least one of --grades / --events / --tokens must be supplied. + """; + + public static bool TryParse(string[] args, out ImportOptions options, out string? error) + { + options = new ImportOptions(); + error = null; + + for (var i = 0; i < args.Length; i++) + { + var arg = args[i]; + string? Next() => i + 1 < args.Length ? args[++i] : null; + + switch (arg) + { + case "--course": options.CourseSlug = Next() ?? string.Empty; break; + case "--connection": options.ConnectionString = Next() ?? string.Empty; break; + case "--grades": options.GradesFile = Next(); break; + case "--events": options.EventsFile = Next(); break; + case "--tokens": options.TokensFile = Next(); break; + case "--repo-prefix": options.RepoPrefix = Next(); break; + case "--force": options.Force = true; break; + default: + error = $"Unknown argument: {arg}"; + return false; + } + } + + if (string.IsNullOrWhiteSpace(options.CourseSlug)) + error = "--course is required."; + else if (string.IsNullOrWhiteSpace(options.ConnectionString)) + error = "--connection is required."; + else if (options.GradesFile is null && options.EventsFile is null && options.TokensFile is null) + error = "At least one of --grades / --events / --tokens must be supplied."; + + return error is null; + } +} diff --git a/ahk-backend/Ahk.Web.Import/Importer.cs b/ahk-backend/Ahk.Web.Import/Importer.cs new file mode 100644 index 00000000..8d8b9fdc --- /dev/null +++ b/ahk-backend/Ahk.Web.Import/Importer.cs @@ -0,0 +1,258 @@ +using System.Text.Json; +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Microsoft.EntityFrameworkCore; + +namespace Ahk.Web.Import; + +/// +/// Moves one course's history from the exported CosmosDB JSON into the relational model. +/// +/// Deliberately bypasses Ahk.Web.Services and writes through the DbContext directly: this is bulk movement of +/// records that are already in final shape, not domain operations. It does reuse so the +/// imported rows are identical in shape to runtime-written ones. +/// +/// There is no HTTP scope here, so every read uses IgnoreQueryFilters — the course query filter would otherwise +/// match nothing. +/// +internal sealed class Importer +{ + private static readonly JsonSerializerOptions JsonOptions = new() + { + PropertyNameCaseInsensitive = true, + }; + + private readonly ApplicationDbContext db; + private readonly ImportOptions options; + + // Caches so each distinct neptun/repo produces exactly one row. + private readonly Dictionary students = new(StringComparer.Ordinal); + private readonly Dictionary submissions = new(StringComparer.Ordinal); + + public Importer(ApplicationDbContext db, ImportOptions options) + { + this.db = db; + this.options = options; + } + + public async Task RunAsync() + { + var course = await db.Courses.IgnoreQueryFilters().FirstOrDefaultAsync(c => c.Slug == options.CourseSlug); + if (course is null) + { + Console.Error.WriteLine($"Course '{options.CourseSlug}' does not exist. Create it in the portal first."); + return 1; + } + + if (!options.Force && await HasExistingDataAsync(course.Id)) + { + Console.Error.WriteLine($"Course '{options.CourseSlug}' already has imported data. Re-run with --force to import anyway."); + return 1; + } + + var grades = ReadDocuments(options.GradesFile); + var events = ReadDocuments(options.EventsFile); + var tokens = ReadDocuments(options.TokensFile); + + Console.WriteLine($"Read {grades.Count} grade, {events.Count} event, {tokens.Count} token document(s)."); + + await using var transaction = await db.Database.BeginTransactionAsync(); + + // Order matters for the foreign keys: students and submissions first, then their children. + await PreloadExistingAsync(course.Id); + + var eventCount = await ImportEventsAsync(course.Id, events); + var gradeCount = await ImportGradesAsync(course.Id, grades); + var tokenCount = await ImportTokensAsync(course.Id, tokens); + + await transaction.CommitAsync(); + + Console.WriteLine(); + Console.WriteLine("Import complete:"); + Console.WriteLine($" students : {students.Count}"); + Console.WriteLine($" submissions : {submissions.Count}"); + Console.WriteLine($" events : {eventCount}"); + Console.WriteLine($" grades : {gradeCount}"); + Console.WriteLine($" tokens : {tokenCount}"); + return 0; + } + + private Task HasExistingDataAsync(int courseId) + => db.Submissions.IgnoreQueryFilters().AnyAsync(s => s.CourseId == courseId); + + private async Task PreloadExistingAsync(int courseId) + { + foreach (var s in await db.Students.IgnoreQueryFilters().Where(s => s.CourseId == courseId).ToListAsync()) + students[s.Neptun] = s; + + foreach (var s in await db.Submissions.IgnoreQueryFilters().Where(s => s.CourseId == courseId).ToListAsync()) + submissions[s.GitHubRepoName] = s; + } + + private static List ReadDocuments(string? path) + { + if (string.IsNullOrWhiteSpace(path)) + return new List(); + + if (!File.Exists(path)) + throw new FileNotFoundException($"Export file not found: {path}", path); + + using var stream = File.OpenRead(path); + return JsonSerializer.Deserialize>(stream, JsonOptions) ?? new List(); + } + + private bool IsIncluded(string? repository) + { + if (string.IsNullOrWhiteSpace(repository)) + return false; + + return options.RepoPrefix is null + || Normalize.RepoName(repository).StartsWith(Normalize.RepoName(options.RepoPrefix), StringComparison.Ordinal); + } + + private async Task GetStudentAsync(int courseId, string neptun) + { + var key = Normalize.Neptun(neptun); + if (students.TryGetValue(key, out var existing)) + return existing; + + var student = new Student { CourseId = courseId, Neptun = key }; + db.Students.Add(student); + await db.SaveChangesAsync(); + + students[key] = student; + return student; + } + + private async Task GetSubmissionAsync(int courseId, string repository, string? neptun) + { + var key = Normalize.RepoName(repository); + if (!submissions.TryGetValue(key, out var submission)) + { + submission = new Submission { CourseId = courseId, GitHubRepoName = key }; + db.Submissions.Add(submission); + await db.SaveChangesAsync(); + submissions[key] = submission; + } + + if (!string.IsNullOrWhiteSpace(neptun) && submission.StudentId is null) + { + var student = await GetStudentAsync(courseId, neptun); + submission.StudentId = student.Id; + await db.SaveChangesAsync(); + } + + return submission; + } + + private async Task ImportEventsAsync(int courseId, List documents) + { + var imported = 0; + + foreach (var doc in documents.Where(d => IsIncluded(d.Repository))) + { + var submission = await GetSubmissionAsync(courseId, doc.Repository!, doc.Neptun); + + SubmissionEvent? entity = doc.Type switch + { + LegacyEventTypes.RepositoryCreate => new RepositoryCreatedEvent(), + LegacyEventTypes.BranchCreate => new BranchCreatedEvent { Branch = doc.Branch ?? string.Empty }, + LegacyEventTypes.WorkflowRun => new WorkflowRunEvent { Conclusion = doc.Conclusion }, + LegacyEventTypes.PullRequest => new PullRequestEvent + { + Number = doc.Number, + Action = doc.Action ?? string.Empty, + HtmlUrl = doc.HtmlUrl, + Neptun = string.IsNullOrWhiteSpace(doc.Neptun) ? null : Normalize.Neptun(doc.Neptun), + Assignees = doc.Assignees ?? new List(), + }, + _ => null, + }; + + if (entity is null) + { + Console.Error.WriteLine($" ! skipping event with unknown $type '{doc.Type}' (id {doc.Id})"); + continue; + } + + entity.CourseId = courseId; + entity.SubmissionId = submission.Id; + entity.Timestamp = doc.Timestamp; + + db.SubmissionEvents.Add(entity); + + if (submission.LastEventAt is null || doc.Timestamp > submission.LastEventAt) + submission.LastEventAt = doc.Timestamp; + + imported++; + + if (imported % 500 == 0) + await db.SaveChangesAsync(); + } + + await db.SaveChangesAsync(); + return imported; + } + + private async Task ImportGradesAsync(int courseId, List documents) + { + var imported = 0; + + foreach (var doc in documents.Where(d => IsIncluded(d.GitHubRepoName))) + { + var neptun = Normalize.Neptun(doc.Neptun ?? string.Empty); + var submission = await GetSubmissionAsync(courseId, doc.GitHubRepoName!, neptun); + + var record = new GradeRecord + { + CourseId = courseId, + SubmissionId = submission.Id, + StudentId = submission.StudentId, + Neptun = neptun, + PrNumber = doc.GitHubPrNumber, + PrUrl = doc.GitHubPrUrl, + Date = doc.Date, + Actor = doc.Actor, + Origin = doc.Origin, + Confirmed = doc.Confirmed, + }; + + var order = 0; + foreach (var p in doc.Points ?? new List()) + record.Points.Add(new GradeExercisePoint { Name = p.Name ?? string.Empty, Point = p.Point, Order = order++ }); + + db.GradeRecords.Add(record); + imported++; + + if (imported % 500 == 0) + await db.SaveChangesAsync(); + } + + await db.SaveChangesAsync(); + return imported; + } + + private async Task ImportTokensAsync(int courseId, List documents) + { + var imported = 0; + + foreach (var doc in documents.Where(d => !string.IsNullOrWhiteSpace(d.Id))) + { + var exists = await db.CourseWebhookTokens.IgnoreQueryFilters().AnyAsync(t => t.Token == doc.Id); + if (exists) + continue; + + db.CourseWebhookTokens.Add(new CourseWebhookToken + { + CourseId = courseId, + Token = doc.Id!, + Secret = doc.Secret ?? string.Empty, + Description = doc.Description, + }); + imported++; + } + + await db.SaveChangesAsync(); + return imported; + } +} diff --git a/ahk-backend/Ahk.Web.Import/Program.cs b/ahk-backend/Ahk.Web.Import/Program.cs new file mode 100644 index 00000000..14c69e84 --- /dev/null +++ b/ahk-backend/Ahk.Web.Import/Program.cs @@ -0,0 +1,46 @@ +using Ahk.Web.Data; +using Microsoft.EntityFrameworkCore; + +namespace Ahk.Web.Import; + +/// +/// Entry point for the one-time CosmosDB -> MSSQL import. This project is throwaway: delete it once every +/// course's history has been migrated. +/// +public static class Program +{ + public static async Task Main(string[] args) + { + if (args.Length == 0 || args.Contains("--help") || args.Contains("-h")) + { + Console.WriteLine(ImportOptions.Usage); + return 0; + } + + if (!ImportOptions.TryParse(args, out var options, out var error)) + { + Console.Error.WriteLine(error); + Console.Error.WriteLine(); + Console.Error.WriteLine(ImportOptions.Usage); + return 1; + } + + var dbOptions = new DbContextOptionsBuilder() + .UseSqlServer(options.ConnectionString) + .Options; + + // No HTTP scope: a null current course means the query filter matches nothing, so the importer reads + // with IgnoreQueryFilters throughout. + await using var db = new ApplicationDbContext(dbOptions, new NullCurrentCourseProvider()); + + try + { + return await new Importer(db, options).RunAsync(); + } + catch (Exception ex) + { + Console.Error.WriteLine($"Import failed: {ex.Message}"); + return 1; + } + } +} diff --git a/ahk-backend/Ahk.Web.Server.Tests/ApiSmokeTests.cs b/ahk-backend/Ahk.Web.Server.Tests/ApiSmokeTests.cs index 51591ed3..f73a42f0 100644 --- a/ahk-backend/Ahk.Web.Server.Tests/ApiSmokeTests.cs +++ b/ahk-backend/Ahk.Web.Server.Tests/ApiSmokeTests.cs @@ -1,10 +1,13 @@ using System.Linq; using System.Net; using Ahk.Web.Data; +using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Options; using Xunit; namespace Ahk.Web.Server.Tests; @@ -27,11 +30,48 @@ public async Task Me_WithoutAuth_Returns401() Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); } + /// + /// The auth cookies must keep app-specific names. Browsers scope cookies by host and ignore the port, so + /// on the framework default every ASP.NET Identity app on localhost shares one cookie — and a foreign one + /// carrying a GUID user id crashes this app's int-keyed Identity inside SecurityStampValidator. + /// [Fact] - public async Task AdminCourses_WithoutAuth_Returns401() + public void AuthCookies_AreNamedForThisApp() + { + var options = factory.Services + .GetRequiredService>(); + + Assert.Equal(Program.ApplicationCookieName, options.Get(IdentityConstants.ApplicationScheme).Cookie.Name); + Assert.Equal(Program.ExternalCookieName, options.Get(IdentityConstants.ExternalScheme).Cookie.Name); + Assert.DoesNotContain("AspNetCore.Identity", Program.ApplicationCookieName, StringComparison.Ordinal); + } + + /// A cookie this app cannot read must sign the caller out, not surface as a 500. + [Fact] + public async Task UnreadableAuthCookie_Returns401_NotAnError() + { + var client = factory.CreateClient(); + client.DefaultRequestHeaders.Add("Cookie", $"{Program.ApplicationCookieName}=not-a-real-cookie-value"); + + var response = await client.GetAsync("/api/auth/me"); + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); + } + + /// Every host/admin surface is behind the site-admin role, including the ones added for the admin UI. + [Theory] + [InlineData("/api/admin/courses")] + [InlineData("/api/admin/courses/1")] + [InlineData("/api/admin/courses/1/github")] + [InlineData("/api/admin/courses/1/members")] + [InlineData("/api/admin/courses/1/tokens")] + [InlineData("/api/admin/users")] + [InlineData("/api/admin/users/1")] + [InlineData("/api/admin/health")] + [InlineData("/api/admin/health/1")] + public async Task AdminEndpoints_WithoutAuth_Return401(string url) { var client = factory.CreateClient(); - var response = await client.GetAsync("/api/admin/courses"); + var response = await client.GetAsync(url); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); } @@ -39,7 +79,7 @@ public async Task AdminCourses_WithoutAuth_Returns401() public async Task UnknownCourseSlug_Returns404_BeforeAuth() { var client = factory.CreateClient(); - var response = await client.GetAsync("/api/no-such-course/probe/notes"); + var response = await client.GetAsync("/api/no-such-course/statuses"); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } diff --git a/ahk-backend/Ahk.Web.Server.Tests/CourseHealthTests.cs b/ahk-backend/Ahk.Web.Server.Tests/CourseHealthTests.cs new file mode 100644 index 00000000..170ff940 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server.Tests/CourseHealthTests.cs @@ -0,0 +1,134 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Ahk.Web.Services.Health; +using Microsoft.EntityFrameworkCore; +using Xunit; + +namespace Ahk.Web.Server.Tests; + +/// +/// Covers the course health checks and how their results aggregate. The network-bound GitHub check is not +/// exercised here; the local checks and the aggregation rule are what the admin dashboard's traffic lights +/// are actually derived from. +/// +public class CourseHealthTests +{ + private sealed class NoCourseProvider : ICurrentCourseProvider + { + public int? CurrentCourseId => null; + } + + private static ApplicationDbContext CreateContext(string dbName) => + new(new DbContextOptionsBuilder().UseInMemoryDatabase(dbName).Options, new NoCourseProvider()); + + private static Course CourseWith(CourseGitHubConfig? config, string? org = "ahk-viaubc01") => + new() { Id = 1, Slug = "viaubc01", Name = "Sample", GitHubOrganization = org, GitHubConfig = config }; + + // ---- Webhook settings ---- + + [Fact] + public async Task WebhookCheck_ReportsNotConfigured_WithoutAnOrganization() + { + var result = await new WebhookConfigurationHealthCheck().RunAsync(CourseWith(new CourseGitHubConfig(), org: null)); + Assert.Equal(HealthStatus.NotConfigured, result.Status); + } + + [Fact] + public async Task WebhookCheck_WarnsWhenTheSignatureCannotBeValidated() + { + var result = await new WebhookConfigurationHealthCheck().RunAsync(CourseWith(new CourseGitHubConfig())); + Assert.Equal(HealthStatus.Warning, result.Status); + Assert.NotNull(result.Remediation); + } + + [Fact] + public async Task WebhookCheck_WarnsWhenTheIntegrationIsSwitchedOff() + { + var config = new CourseGitHubConfig { GitHubWebhookSecret = "s3cret", Enabled = false }; + var result = await new WebhookConfigurationHealthCheck().RunAsync(CourseWith(config)); + Assert.Equal(HealthStatus.Warning, result.Status); + } + + [Fact] + public async Task WebhookCheck_PassesWhenOrganizationAndSecretAreSet() + { + var config = new CourseGitHubConfig { GitHubWebhookSecret = "s3cret", Enabled = true }; + var result = await new WebhookConfigurationHealthCheck().RunAsync(CourseWith(config)); + Assert.Equal(HealthStatus.Healthy, result.Status); + } + + // ---- CI callback token ---- + + [Fact] + public async Task TokenCheck_ReportsNotConfigured_WhenNoTokenWasEverIssued() + { + await using var db = CreateContext(Guid.NewGuid().ToString()); + var result = await new CiCallbackTokenHealthCheck(db).RunAsync(CourseWith(new CourseGitHubConfig())); + Assert.Equal(HealthStatus.NotConfigured, result.Status); + } + + [Fact] + public async Task TokenCheck_FailsWhenEveryTokenIsRevoked() + { + var dbName = Guid.NewGuid().ToString(); + await using (var seed = CreateContext(dbName)) + { + seed.CourseWebhookTokens.Add(new CourseWebhookToken + { + CourseId = 1, + Token = "t", + Secret = "s", + RevokedAt = DateTimeOffset.UtcNow, + }); + await seed.SaveChangesAsync(); + } + + await using var db = CreateContext(dbName); + var result = await new CiCallbackTokenHealthCheck(db).RunAsync(CourseWith(new CourseGitHubConfig())); + Assert.Equal(HealthStatus.Failed, result.Status); + } + + /// + /// The check runs in the host/admin context, where no current course is set — so it must bypass the course + /// query filter, or it would report every course as having no token. + /// + [Fact] + public async Task TokenCheck_SeesTokens_EvenWithNoCurrentCourseResolved() + { + var dbName = Guid.NewGuid().ToString(); + await using (var seed = CreateContext(dbName)) + { + seed.CourseWebhookTokens.Add(new CourseWebhookToken { CourseId = 1, Token = "t", Secret = "s" }); + await seed.SaveChangesAsync(); + } + + await using var db = CreateContext(dbName); + var result = await new CiCallbackTokenHealthCheck(db).RunAsync(CourseWith(new CourseGitHubConfig())); + Assert.Equal(HealthStatus.Healthy, result.Status); + } + + // ---- Aggregation ---- + + [Theory] + [InlineData(HealthStatus.Healthy, HealthStatus.NotConfigured, HealthStatus.Healthy)] + [InlineData(HealthStatus.Healthy, HealthStatus.Warning, HealthStatus.Warning)] + [InlineData(HealthStatus.Warning, HealthStatus.Failed, HealthStatus.Failed)] + [InlineData(HealthStatus.NotConfigured, HealthStatus.NotConfigured, HealthStatus.NotConfigured)] + public void Report_TakesTheWorstCheckStatus(HealthStatus first, HealthStatus second, HealthStatus expected) + { + var report = new CourseHealthReport + { + Checks = new[] + { + new HealthCheckResult { Status = first }, + new HealthCheckResult { Status = second }, + }, + }; + + Assert.Equal(expected, report.Status); + } + + [Fact] + public void Report_WithNoChecks_IsNotConfigured() => + Assert.Equal(HealthStatus.NotConfigured, new CourseHealthReport().Status); +} diff --git a/ahk-backend/Ahk.Web.Server.Tests/CourseScopingTests.cs b/ahk-backend/Ahk.Web.Server.Tests/CourseScopingTests.cs index 157587f4..554b6bf8 100644 --- a/ahk-backend/Ahk.Web.Server.Tests/CourseScopingTests.cs +++ b/ahk-backend/Ahk.Web.Server.Tests/CourseScopingTests.cs @@ -6,14 +6,15 @@ namespace Ahk.Web.Server.Tests; /// -/// Verifies the EF Core course query filter: a request scoped to one course only sees that course's rows. -/// This is the core isolation mechanism, so it is exercised directly against the DbContext. +/// Verifies the EF Core course query filter across the domain entities: a request scoped to one course only +/// sees that course's rows. This is the isolation mechanism the whole portal relies on, so it is exercised +/// directly against the DbContext. /// public class CourseScopingTests { private sealed class MutableCourseProvider : ICurrentCourseProvider { - public Guid? CurrentCourseId { get; set; } + public int? CurrentCourseId { get; set; } } private static ApplicationDbContext CreateContext(ICurrentCourseProvider provider, string dbName) @@ -24,50 +25,94 @@ private static ApplicationDbContext CreateContext(ICurrentCourseProvider provide return new ApplicationDbContext(options, provider); } - [Fact] - public async Task CourseNotes_AreFilteredToTheCurrentCourse() + private const int CourseA = 1; + private const int CourseB = 2; + + /// Seeds one submission with an event and a grade for each of two courses. + private static async Task SeedTwoCoursesAsync(string dbName) { - var dbName = Guid.NewGuid().ToString(); - var courseA = Guid.NewGuid(); - var courseB = Guid.NewGuid(); + await using var db = CreateContext(new MutableCourseProvider { CurrentCourseId = null }, dbName); - // Seed notes for two courses using an unscoped provider (null → filter matches nothing, so use raw add). - var seedProvider = new MutableCourseProvider { CurrentCourseId = null }; - await using (var seed = CreateContext(seedProvider, dbName)) + foreach (var (courseId, repo, neptun) in new[] { (CourseA, "org/a-hw1-abc123", "ABC123"), (CourseB, "org/b-hw1-xyz789", "XYZ789") }) { - seed.CourseNotes.Add(new CourseNote { CourseId = courseA, Text = "A1" }); - seed.CourseNotes.Add(new CourseNote { CourseId = courseA, Text = "A2" }); - seed.CourseNotes.Add(new CourseNote { CourseId = courseB, Text = "B1" }); - await seed.SaveChangesAsync(); - } + var student = new Student { CourseId = courseId, Neptun = neptun }; + db.Students.Add(student); + await db.SaveChangesAsync(); - var provider = new MutableCourseProvider { CurrentCourseId = courseA }; - await using (var scoped = CreateContext(provider, dbName)) - { - var notes = await scoped.CourseNotes.ToListAsync(); - Assert.Equal(2, notes.Count); - Assert.All(notes, n => Assert.Equal(courseA, n.CourseId)); - } + var submission = new Submission { CourseId = courseId, StudentId = student.Id, GitHubRepoName = repo }; + db.Submissions.Add(submission); + await db.SaveChangesAsync(); - provider.CurrentCourseId = courseB; - await using (var scoped = CreateContext(provider, dbName)) - { - var notes = await scoped.CourseNotes.ToListAsync(); - Assert.Single(notes); - Assert.Equal("B1", notes[0].Text); + db.SubmissionEvents.Add(new BranchCreatedEvent + { + CourseId = courseId, + SubmissionId = submission.Id, + Timestamp = DateTimeOffset.UtcNow, + Branch = "solution", + }); + + var grade = new GradeRecord + { + CourseId = courseId, + SubmissionId = submission.Id, + StudentId = student.Id, + Neptun = neptun, + Date = DateTimeOffset.UtcNow, + Confirmed = true, + }; + grade.Points.Add(new GradeExercisePoint { Name = "ex0", Point = 1, Order = 0 }); + db.GradeRecords.Add(grade); + + await db.SaveChangesAsync(); } } + [Theory] + [InlineData(CourseA, "org/a-hw1-abc123")] + [InlineData(CourseB, "org/b-hw1-xyz789")] + public async Task Submissions_AreFilteredToTheCurrentCourse(int courseId, string expectedRepo) + { + var dbName = Guid.NewGuid().ToString(); + await SeedTwoCoursesAsync(dbName); + + await using var db = CreateContext(new MutableCourseProvider { CurrentCourseId = courseId }, dbName); + + var submissions = await db.Submissions.ToListAsync(); + Assert.Single(submissions); + Assert.Equal(expectedRepo, submissions[0].GitHubRepoName); + } + + [Fact] + public async Task Students_Events_AndGrades_AreFilteredToTheCurrentCourse() + { + var dbName = Guid.NewGuid().ToString(); + await SeedTwoCoursesAsync(dbName); + + await using var db = CreateContext(new MutableCourseProvider { CurrentCourseId = CourseA }, dbName); + + Assert.All(await db.Students.ToListAsync(), s => Assert.Equal(CourseA, s.CourseId)); + Assert.All(await db.SubmissionEvents.ToListAsync(), e => Assert.Equal(CourseA, e.CourseId)); + Assert.All(await db.GradeRecords.ToListAsync(), g => Assert.Equal(CourseA, g.CourseId)); + + Assert.Single(await db.GradeRecords.ToListAsync()); + } + + /// + /// Guards the trap called out in the plan: with no course resolved (machine-to-machine paths, the importer) + /// the filter matches nothing, so such callers must set a provider or use IgnoreQueryFilters. + /// [Fact] - public async Task CourseNotes_AreHiddenWhenNoCourseIsResolved() + public async Task NoCurrentCourse_HidesAllCourseScopedRows() { var dbName = Guid.NewGuid().ToString(); - var provider = new MutableCourseProvider { CurrentCourseId = null }; - await using var db = CreateContext(provider, dbName); + await SeedTwoCoursesAsync(dbName); + + await using var db = CreateContext(new MutableCourseProvider { CurrentCourseId = null }, dbName); - db.CourseNotes.Add(new CourseNote { CourseId = Guid.NewGuid(), Text = "orphan" }); - await db.SaveChangesAsync(); + Assert.Empty(await db.Submissions.ToListAsync()); + Assert.Empty(await db.GradeRecords.ToListAsync()); - Assert.Empty(await db.CourseNotes.ToListAsync()); + // ...but the rows are there when the filter is bypassed. + Assert.Equal(2, await db.Submissions.IgnoreQueryFilters().CountAsync()); } } diff --git a/ahk-backend/Ahk.Web.Server.Tests/ExternalClaimsMapperTests.cs b/ahk-backend/Ahk.Web.Server.Tests/ExternalClaimsMapperTests.cs new file mode 100644 index 00000000..2a6c6fa3 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server.Tests/ExternalClaimsMapperTests.cs @@ -0,0 +1,118 @@ +using System.Security.Claims; +using Ahk.Web.Data.Entities; +using Ahk.Web.Server.Auth; +using Xunit; + +namespace Ahk.Web.Server.Tests; + +/// +/// Covers projecting a BME OIDC identity onto the local user: the claim names, the multi-valued affiliation, +/// and the rule that absent claims must never wipe values already stored. +/// +public class ExternalClaimsMapperTests +{ + private static ClaimsPrincipal Principal(params Claim[] claims) + => new(new ClaimsIdentity(claims, authenticationType: "oidc")); + + [Fact] + public void SyncFromClaims_MapsAllBmeClaims() + { + var user = new ApplicationUser(); + var principal = Principal( + new Claim(ClaimTypes.Email, "teacher@bme.hu"), + new Claim(ClaimTypes.Name, "Teszt Tanár"), + new Claim(BmeClaimTypes.NeptunCode, "teach1"), + new Claim(BmeClaimTypes.Affiliation, "staff@bme.hu;employee@bme.hu")); + + var changed = ExternalClaimsMapper.SyncFromClaims(user, principal); + + Assert.True(changed); + Assert.Equal("teacher@bme.hu", user.Email); + Assert.Equal("Teszt Tanár", user.DisplayName); + Assert.Equal("TEACH1", user.NeptunCode); // normalized to upper, like the domain model + Assert.Equal("staff@bme.hu;employee@bme.hu", user.Affiliation); + } + + [Fact] + public void SyncFromClaims_ComposesDisplayNameFromGivenAndFamilyName() + { + var user = new ApplicationUser(); + var principal = Principal( + new Claim(ClaimTypes.GivenName, "Teszt"), + new Claim(ClaimTypes.Surname, "Tanár")); + + ExternalClaimsMapper.SyncFromClaims(user, principal); + + Assert.Equal("Teszt Tanár", user.DisplayName); + } + + [Fact] + public void SyncFromClaims_JoinsRepeatedAffiliationClaims() + { + var principal = Principal( + new Claim(BmeClaimTypes.Affiliation, "staff@bme.hu"), + new Claim(BmeClaimTypes.Affiliation, "employee@bme.hu"), + new Claim(BmeClaimTypes.Affiliation, "staff@bme.hu")); // duplicate collapses + + Assert.Equal("staff@bme.hu;employee@bme.hu", ExternalClaimsMapper.ResolveAffiliation(principal)); + } + + [Fact] + public void SyncFromClaims_SparseIdentity_LeavesOptionalFieldsNull() + { + var user = new ApplicationUser(); + var principal = Principal(new Claim(ClaimTypes.Email, "sparse@bme.hu")); + + ExternalClaimsMapper.SyncFromClaims(user, principal); + + Assert.Equal("sparse@bme.hu", user.Email); + Assert.Null(user.NeptunCode); + Assert.Null(user.Affiliation); + } + + [Fact] + public void SyncFromClaims_MissingClaims_DoNotWipeStoredValues() + { + var user = new ApplicationUser + { + Email = "teacher@bme.hu", + DisplayName = "Teszt Tanár", + NeptunCode = "TEACH1", + Affiliation = "staff@bme.hu", + }; + + // A later login where the directory returned nothing extra. + var changed = ExternalClaimsMapper.SyncFromClaims(user, Principal()); + + Assert.False(changed); + Assert.Equal("TEACH1", user.NeptunCode); + Assert.Equal("staff@bme.hu", user.Affiliation); + } + + [Fact] + public void SyncFromClaims_ReportsNoChange_WhenValuesAlreadyMatch() + { + var user = new ApplicationUser { Email = "teacher@bme.hu", DisplayName = "Teszt Tanár", NeptunCode = "TEACH1" }; + var principal = Principal( + new Claim(ClaimTypes.Email, "teacher@bme.hu"), + new Claim(ClaimTypes.Name, "Teszt Tanár"), + new Claim(BmeClaimTypes.NeptunCode, "TEACH1")); + + Assert.False(ExternalClaimsMapper.SyncFromClaims(user, principal)); + } + + [Fact] + public void SyncFromClaims_UpdatesChangedDirectoryData() + { + var user = new ApplicationUser { Email = "old@bme.hu", DisplayName = "Old Name", NeptunCode = "OLD123" }; + var principal = Principal( + new Claim(ClaimTypes.Email, "new@bme.hu"), + new Claim(ClaimTypes.Name, "New Name"), + new Claim(BmeClaimTypes.NeptunCode, "NEW456")); + + Assert.True(ExternalClaimsMapper.SyncFromClaims(user, principal)); + Assert.Equal("new@bme.hu", user.Email); + Assert.Equal("New Name", user.DisplayName); + Assert.Equal("NEW456", user.NeptunCode); + } +} diff --git a/ahk-backend/Ahk.Web.Server.Tests/GradeLogicParityTests.cs b/ahk-backend/Ahk.Web.Server.Tests/GradeLogicParityTests.cs new file mode 100644 index 00000000..fd2200b5 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server.Tests/GradeLogicParityTests.cs @@ -0,0 +1,118 @@ +using Ahk.Web.Data.Entities; +using Ahk.Web.Services.Grading; +using Ahk.Web.Services.Grading.Dto; +using Xunit; + +namespace Ahk.Web.Server.Tests; + +/// +/// Parity checks for the grade logic ported from grade-management. The expectations mirror +/// ResultProcessor.GetTotalPoints and SetGradeService.getPoints; if these drift, grades change +/// meaning for existing courses. +/// +public class GradeLogicParityTests +{ + [Fact] + public void AggregatePoints_SumsTasksPerExercise_OrderedByName() + { + var tasks = new[] + { + new EvaluationTaskResult { ExerciseName = "ex2", TaskName = "t1", Points = 1 }, + new EvaluationTaskResult { ExerciseName = "ex1", TaskName = "t2", Points = 2 }, + new EvaluationTaskResult { ExerciseName = "ex1", TaskName = "t3", Points = 3 }, + }; + + var result = GradeService.AggregatePoints(tasks); + + Assert.Equal(2, result.Count); + Assert.Equal("ex1", result[0].Name); + Assert.Equal(5, result[0].Point); // 2 + 3 summed + Assert.Equal("ex2", result[1].Name); + Assert.Equal(1, result[1].Point); + } + + [Fact] + public void AggregatePoints_TreatsMissingExerciseNameAsEmptyGroup() + { + var tasks = new[] + { + new EvaluationTaskResult { ExerciseName = null, TaskName = "t1", Points = 2 }, + new EvaluationTaskResult { ExerciseName = string.Empty, TaskName = "t2", Points = 3 }, + }; + + var result = GradeService.AggregatePoints(tasks); + + Assert.Single(result); + Assert.Equal(string.Empty, result[0].Name); + Assert.Equal(5, result[0].Point); + } + + [Fact] + public void AggregatePoints_HandlesNoTasks() + => Assert.Empty(GradeService.AggregatePoints(Array.Empty())); + + [Fact] + public void BuildPoints_UsesPositionalDefaultNames_WhenNoPreviousResult() + { + var result = GradeService.BuildPoints(new[] { 5d, 3.5d, 0d }, previousPoints: null); + + Assert.Equal(new[] { "ex0", "ex1", "ex2" }, result.Select(p => p.Name)); + Assert.Equal(new[] { 5d, 3.5d, 0d }, result.Select(p => p.Point)); + } + + [Fact] + public void BuildPoints_CarriesForwardPreviousExerciseNames() + { + var previous = new List + { + new() { Name = "Exercise 1", Point = 1, Order = 0 }, + new() { Name = "Exercise 2", Point = 2, Order = 1 }, + }; + + var result = GradeService.BuildPoints(new[] { 5d, 4d }, previous); + + Assert.Equal(new[] { "Exercise 1", "Exercise 2" }, result.Select(p => p.Name)); + Assert.Equal(new[] { 5d, 4d }, result.Select(p => p.Point)); + } + + [Fact] + public void BuildPoints_FallsBackToPositionalNames_BeyondPreviousCount() + { + var previous = new List { new() { Name = "Exercise 1", Point = 1, Order = 0 } }; + + var result = GradeService.BuildPoints(new[] { 5d, 4d }, previous); + + Assert.Equal(new[] { "Exercise 1", "ex1" }, result.Select(p => p.Name)); + } + + [Fact] + public void CsvExporter_PreservesLegacyFormat() + { + var grades = new[] + { + new FinalStudentGrade + { + Neptun = "abc123", + Repo = "org/course-hw1-abc123", + PrUrl = "https://github.com/org/course-hw1-abc123/pull/1", + Points = new Dictionary { ["ex0"] = 2, ["ex1"] = 3.5 }, + }, + new FinalStudentGrade + { + Neptun = "XYZ789", + Repo = "org/course-hw1-xyz789", + PrUrl = null, + Points = new Dictionary { ["ex0"] = 1 }, + }, + }; + + var csv = CsvExporter.GetCsv(grades); + var lines = csv.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries); + + Assert.Equal("Neptun;GitHubRepo;GitHubPr;ex0;ex1", lines[0]); + Assert.Equal("ABC123;org/course-hw1-abc123;https://github.com/org/course-hw1-abc123/pull/1;2;3.5", lines[1]); + + // Missing exercise -> empty cell; missing PR url -> empty cell. + Assert.Equal("XYZ789;org/course-hw1-xyz789;;1;", lines[2]); + } +} diff --git a/ahk-backend/Ahk.Web.Server.Tests/StatusProjectionTests.cs b/ahk-backend/Ahk.Web.Server.Tests/StatusProjectionTests.cs new file mode 100644 index 00000000..adabcd1f --- /dev/null +++ b/ahk-backend/Ahk.Web.Server.Tests/StatusProjectionTests.cs @@ -0,0 +1,101 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Ahk.Web.Services.StatusTracking; +using Microsoft.EntityFrameworkCore; +using Xunit; + +namespace Ahk.Web.Server.Tests; + +/// +/// Parity checks for the event-log → status projection ported from +/// grade-management/.../StatusTracking/StatusTrackingService.cs: latest PR action wins, assignees are +/// the distinct union, branches are distinct, and workflow runs report count + last conclusion. +/// +public class StatusProjectionTests +{ + private sealed class FixedCourseProvider : ICurrentCourseProvider + { + public int? CurrentCourseId { get; set; } + } + + private const int CourseId = 1; + + private static ApplicationDbContext CreateContext(string dbName) + { + var options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(dbName) + .Options; + return new ApplicationDbContext(options, new FixedCourseProvider { CurrentCourseId = CourseId }); + } + + private static async Task SeedAsync() + { + var db = CreateContext(Guid.NewGuid().ToString()); + var now = DateTimeOffset.UtcNow; + + var student = new Student { CourseId = CourseId, Neptun = "ABC123" }; + db.Students.Add(student); + await db.SaveChangesAsync(); + + var submission = new Submission { CourseId = CourseId, StudentId = student.Id, GitHubRepoName = "org/course-hw1-abc123" }; + db.Submissions.Add(submission); + await db.SaveChangesAsync(); + + db.SubmissionEvents.AddRange( + new RepositoryCreatedEvent { CourseId = CourseId, SubmissionId = submission.Id, Timestamp = now.AddDays(-5) }, + new BranchCreatedEvent { CourseId = CourseId, SubmissionId = submission.Id, Timestamp = now.AddDays(-4), Branch = "solution" }, + new BranchCreatedEvent { CourseId = CourseId, SubmissionId = submission.Id, Timestamp = now.AddDays(-4), Branch = "solution" }, + new PullRequestEvent + { + CourseId = CourseId, SubmissionId = submission.Id, Timestamp = now.AddDays(-3), + Number = 1, Action = "opened", HtmlUrl = "https://github.com/org/course-hw1-abc123/pull/1", + Neptun = "ABC123", Assignees = new List { "teacher1" }, + }, + new PullRequestEvent + { + CourseId = CourseId, SubmissionId = submission.Id, Timestamp = now.AddDays(-1), + Number = 1, Action = "closed", HtmlUrl = "https://github.com/org/course-hw1-abc123/pull/1", + Neptun = "ABC123", Assignees = new List { "teacher2" }, + }, + new WorkflowRunEvent { CourseId = CourseId, SubmissionId = submission.Id, Timestamp = now.AddDays(-3), Conclusion = "failure" }, + new WorkflowRunEvent { CourseId = CourseId, SubmissionId = submission.Id, Timestamp = now.AddDays(-2), Conclusion = "success" }); + + await db.SaveChangesAsync(); + return db; + } + + [Fact] + public async Task Projection_MatchesLegacySemantics() + { + await using var db = await SeedAsync(); + var service = new StatusTrackingService(db); + + var statuses = await service.ListStatusesAsync(CourseId); + + var status = Assert.Single(statuses); + Assert.Equal("org/course-hw1-abc123", status.Repository); + Assert.Equal("ABC123", status.Neptun); + + // Branches are distinct. + Assert.Equal(new[] { "solution" }, status.Branches); + + // One PR, latest action wins, assignees are the distinct union across its events. + var pr = Assert.Single(status.PullRequests); + Assert.Equal(1, pr.Number); + Assert.Equal("closed", pr.Status); + Assert.Equal("teacher1, teacher2", pr.Assignee); + + // Workflow runs: total count and the most recent conclusion. + Assert.Equal(2, status.WorkflowRuns.Count); + Assert.Equal("success", status.WorkflowRuns.LastStatus); + } + + [Fact] + public async Task Projection_ReturnsNothingForAnotherCourse() + { + await using var db = await SeedAsync(); + var service = new StatusTrackingService(db); + + Assert.Empty(await service.ListStatusesAsync(courseId: 999)); + } +} diff --git a/ahk-backend/Ahk.Web.Server/Admin/CourseHealthAdminController.cs b/ahk-backend/Ahk.Web.Server/Admin/CourseHealthAdminController.cs new file mode 100644 index 00000000..d70a5fc0 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Admin/CourseHealthAdminController.cs @@ -0,0 +1,39 @@ +using Ahk.Web.Data; +using Ahk.Web.Services.Health; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace Ahk.Web.Server.Admin; + +/// +/// Runs the course health checks on demand. Results are computed per request and never cached: an admin opens +/// this page precisely because they want to know the state right now, usually after changing a credential. +/// +/// Checks are discovered through DI (), so extending what "healthy" means +/// requires no change here. +/// +[ApiController] +[Route("api/admin/health")] +[Authorize(Roles = Roles.Admin)] +public sealed class CourseHealthAdminController : ControllerBase +{ + private readonly ICourseHealthService health; + + public CourseHealthAdminController(ICourseHealthService health) => this.health = health; + + /// Health of every course — the admin health dashboard. + [HttpGet] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + public async Task>> CheckAll(CancellationToken cancellationToken) => + Ok(await health.CheckAllCoursesAsync(cancellationToken)); + + /// Health of one course — used by the re-check button on the course editor. + [HttpGet("{courseId:int}")] + [ProducesResponseType(typeof(CourseHealthReport), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> CheckCourse(int courseId, CancellationToken cancellationToken) + { + var report = await health.CheckCourseAsync(courseId, cancellationToken); + return report is null ? NotFound() : Ok(report); + } +} diff --git a/ahk-backend/Ahk.Web.Server/Admin/CoursesAdminController.cs b/ahk-backend/Ahk.Web.Server/Admin/CoursesAdminController.cs index a396c710..7638e71c 100644 --- a/ahk-backend/Ahk.Web.Server/Admin/CoursesAdminController.cs +++ b/ahk-backend/Ahk.Web.Server/Admin/CoursesAdminController.cs @@ -1,6 +1,7 @@ using Ahk.Web.Data; using Ahk.Web.Data.Entities; using Ahk.Web.Server.Admin.Dto; +using Ahk.Web.Services.Courses; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; @@ -8,8 +9,13 @@ namespace Ahk.Web.Server.Admin; /// -/// Host/admin context (no {course} segment): site super-admins manage the set of courses and, later, their -/// connected GitHub environments. This centralizes what used to be a separate per-course Azure deployment. +/// Host/admin context (no {course} segment): site super-admins manage the set of courses, their connected +/// GitHub environments, their staff and their CI callback tokens. This centralizes what used to be a separate +/// per-course Azure deployment plus its AHK_* application settings. +/// +/// Reads of course-scoped entities (students, submissions, grades, tokens) use IgnoreQueryFilters() and +/// filter on CourseId themselves: there is no {course} segment here, so no current course is set and the +/// course filter would otherwise match nothing. /// [ApiController] [Route("api/admin/courses")] @@ -17,12 +23,17 @@ namespace Ahk.Web.Server.Admin; public sealed class CoursesAdminController : ControllerBase { private readonly ApplicationDbContext db; + private readonly IWebhookTokenService webhookTokens; - public CoursesAdminController(ApplicationDbContext db) => this.db = db; + public CoursesAdminController(ApplicationDbContext db, IWebhookTokenService webhookTokens) + { + this.db = db; + this.webhookTokens = webhookTokens; + } [HttpGet] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - public async Task>> List() + public async Task>> List(CancellationToken cancellationToken) { var courses = await db.Courses .AsNoTracking() @@ -33,43 +44,324 @@ public async Task>> List() Slug = c.Slug, Name = c.Name, GitHubOrganization = c.GitHubOrganization, + RepoNamePrefix = c.RepoNamePrefix, CreatedAt = c.CreatedAt, + IntegrationEnabled = c.GitHubConfig != null && c.GitHubConfig.Enabled, + MemberCount = c.Memberships.Count, + StudentCount = db.Students.IgnoreQueryFilters().Count(s => s.CourseId == c.Id), + SubmissionCount = db.Submissions.IgnoreQueryFilters().Count(s => s.CourseId == c.Id), }) - .ToListAsync(); + .ToListAsync(cancellationToken); return Ok(courses); } - [HttpGet("{id:guid}")] - [ProducesResponseType(typeof(CourseDto), StatusCodes.Status200OK)] + [HttpGet("{id:int}")] + [ProducesResponseType(typeof(CourseDetailDto), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task> Get(Guid id) + public async Task> Get(int id, CancellationToken cancellationToken) { - var course = await db.Courses.AsNoTracking().FirstOrDefaultAsync(c => c.Id == id); - return course is null ? NotFound() : Ok(ToDto(course)); + var course = await db.Courses + .AsNoTracking() + .Include(c => c.GitHubConfig) + .FirstOrDefaultAsync(c => c.Id == id, cancellationToken); + + if (course is null) + return NotFound(); + + var members = await db.CourseMemberships + .AsNoTracking() + .Where(m => m.CourseId == id) + .OrderBy(m => m.User!.UserName) + .Select(m => new CourseMemberDto + { + UserId = m.UserId, + UserName = m.User!.UserName ?? string.Empty, + DisplayName = m.User.DisplayName, + Email = m.User.Email, + Role = m.Role, + }) + .ToListAsync(cancellationToken); + + var tokens = await webhookTokens.ListForCourseAsync(id, cancellationToken); + + return Ok(new CourseDetailDto + { + Id = course.Id, + Slug = course.Slug, + Name = course.Name, + GitHubOrganization = course.GitHubOrganization, + RepoNamePrefix = course.RepoNamePrefix, + CreatedAt = course.CreatedAt, + StudentCount = await db.Students.IgnoreQueryFilters().CountAsync(s => s.CourseId == id, cancellationToken), + SubmissionCount = await db.Submissions.IgnoreQueryFilters().CountAsync(s => s.CourseId == id, cancellationToken), + GitHubConfig = ToDto(course.GitHubConfig), + Members = members, + WebhookTokens = tokens.Select(t => ToDto(t, includeSecret: false)).ToList(), + }); } [HttpPost] - [ProducesResponseType(typeof(CourseDto), StatusCodes.Status201Created)] + [ProducesResponseType(typeof(CourseDetailDto), StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status409Conflict)] - public async Task> Create([FromBody] CreateCourseRequest request) + public async Task> Create([FromBody] CreateCourseRequest request, CancellationToken cancellationToken) { - if (await db.Courses.AnyAsync(c => c.Slug == request.Slug)) + if (await db.Courses.AnyAsync(c => c.Slug == request.Slug, cancellationToken)) return Conflict(new { error = $"A course with slug '{request.Slug}' already exists." }); - var course = new Course { Slug = request.Slug, Name = request.Name, GitHubOrganization = request.GitHubOrganization }; + var course = new Course + { + Slug = request.Slug, + Name = request.Name, + GitHubOrganization = Trimmed(request.GitHubOrganization), + RepoNamePrefix = Trimmed(request.RepoNamePrefix), + + // Created up front so the course editor always has an integration section to fill in. + GitHubConfig = new CourseGitHubConfig(), + }; + db.Courses.Add(course); - await db.SaveChangesAsync(); + await db.SaveChangesAsync(cancellationToken); + + return CreatedAtAction(nameof(Get), new { id = course.Id }, new CourseDetailDto + { + Id = course.Id, + Slug = course.Slug, + Name = course.Name, + GitHubOrganization = course.GitHubOrganization, + RepoNamePrefix = course.RepoNamePrefix, + CreatedAt = course.CreatedAt, + GitHubConfig = ToDto(course.GitHubConfig), + }); + } + + [HttpPut("{id:int}")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(StatusCodes.Status409Conflict)] + public async Task Update(int id, [FromBody] UpdateCourseRequest request, CancellationToken cancellationToken) + { + var course = await db.Courses.FirstOrDefaultAsync(c => c.Id == id, cancellationToken); + if (course is null) + return NotFound(); + + if (!string.Equals(course.Slug, request.Slug, StringComparison.Ordinal) + && await db.Courses.AnyAsync(c => c.Slug == request.Slug && c.Id != id, cancellationToken)) + { + return Conflict(new { error = $"A course with slug '{request.Slug}' already exists." }); + } + + course.Slug = request.Slug; + course.Name = request.Name; + course.GitHubOrganization = Trimmed(request.GitHubOrganization); + course.RepoNamePrefix = Trimmed(request.RepoNamePrefix); + + await db.SaveChangesAsync(cancellationToken); + return NoContent(); + } + + /// + /// Deletes a course and, by cascade, everything assigned to it — students, submissions, events, grades, + /// memberships and tokens. The caller must repeat the slug to confirm, so a mis-clicked id cannot erase a + /// live course's grades. + /// + [HttpDelete("{id:int}")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task Delete(int id, [FromQuery] string? confirmSlug, CancellationToken cancellationToken) + { + var course = await db.Courses.FirstOrDefaultAsync(c => c.Id == id, cancellationToken); + if (course is null) + return NotFound(); + + if (!string.Equals(course.Slug, confirmSlug, StringComparison.Ordinal)) + return BadRequest(new { error = $"Type the course slug '{course.Slug}' to confirm deletion." }); + + // GradeRecord and SubmissionEvent point at Course with NoAction (SQL Server rejects the extra cascade + // paths), so they are removed explicitly before the course goes. + await db.GradeExercisePoints.IgnoreQueryFilters() + .Where(p => p.GradeRecord!.CourseId == id).ExecuteDeleteAsync(cancellationToken); + await db.GradeRecords.IgnoreQueryFilters().Where(g => g.CourseId == id).ExecuteDeleteAsync(cancellationToken); + await db.SubmissionEvents.IgnoreQueryFilters().Where(e => e.CourseId == id).ExecuteDeleteAsync(cancellationToken); + await db.Submissions.IgnoreQueryFilters().Where(s => s.CourseId == id).ExecuteDeleteAsync(cancellationToken); + + db.Courses.Remove(course); + await db.SaveChangesAsync(cancellationToken); + return NoContent(); + } + + // ---- GitHub integration ---- + + [HttpGet("{id:int}/github")] + [ProducesResponseType(typeof(CourseGitHubConfigDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> GetGitHubConfig(int id, CancellationToken cancellationToken) + { + var course = await db.Courses.AsNoTracking().Include(c => c.GitHubConfig) + .FirstOrDefaultAsync(c => c.Id == id, cancellationToken); + + return course is null ? NotFound() : Ok(ToDto(course.GitHubConfig)); + } + + [HttpPut("{id:int}/github")] + [ProducesResponseType(typeof(CourseGitHubConfigDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> UpdateGitHubConfig(int id, [FromBody] UpdateCourseGitHubConfigRequest request, CancellationToken cancellationToken) + { + var course = await db.Courses.Include(c => c.GitHubConfig).FirstOrDefaultAsync(c => c.Id == id, cancellationToken); + if (course is null) + return NotFound(); + + var config = course.GitHubConfig; + if (config is null) + { + config = new CourseGitHubConfig { CourseId = id }; + db.CourseGitHubConfigs.Add(config); + course.GitHubConfig = config; + } + + config.GitHubAppId = Trimmed(request.GitHubAppId); + config.GitHubAppPrivateKey = ApplySecret(config.GitHubAppPrivateKey, request.GitHubAppPrivateKey); + config.GitHubAccessToken = ApplySecret(config.GitHubAccessToken, request.GitHubAccessToken); + config.GitHubWebhookSecret = ApplySecret(config.GitHubWebhookSecret, request.GitHubWebhookSecret); + config.WorkflowRunThreshold = request.WorkflowRunThreshold; + config.Enabled = request.Enabled; + config.UpdatedAt = DateTimeOffset.UtcNow; - return CreatedAtAction(nameof(Get), new { id = course.Id }, ToDto(course)); + await db.SaveChangesAsync(cancellationToken); + return Ok(ToDto(config)); } - private static CourseDto ToDto(Course c) => new() + // ---- Members ---- + + [HttpGet("{id:int}/members")] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + public async Task>> ListMembers(int id, CancellationToken cancellationToken) + { + var members = await db.CourseMemberships + .AsNoTracking() + .Where(m => m.CourseId == id) + .OrderBy(m => m.User!.UserName) + .Select(m => new CourseMemberDto + { + UserId = m.UserId, + UserName = m.User!.UserName ?? string.Empty, + DisplayName = m.User.DisplayName, + Email = m.User.Email, + Role = m.Role, + }) + .ToListAsync(cancellationToken); + + return Ok(members); + } + + /// Adds a user to the course, or changes the role they hold in it. + [HttpPut("{id:int}/members")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task UpsertMember(int id, [FromBody] UpsertCourseMemberRequest request, CancellationToken cancellationToken) + { + if (!await db.Courses.AnyAsync(c => c.Id == id, cancellationToken)) + return NotFound(); + + if (!await db.Users.AnyAsync(u => u.Id == request.UserId, cancellationToken)) + return NotFound(new { error = "No such user." }); + + var membership = await db.CourseMemberships + .FirstOrDefaultAsync(m => m.CourseId == id && m.UserId == request.UserId, cancellationToken); + + if (membership is null) + db.CourseMemberships.Add(new CourseMembership { CourseId = id, UserId = request.UserId, Role = request.Role }); + else + membership.Role = request.Role; + + await db.SaveChangesAsync(cancellationToken); + return NoContent(); + } + + [HttpDelete("{id:int}/members/{userId:int}")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task RemoveMember(int id, int userId, CancellationToken cancellationToken) + { + var membership = await db.CourseMemberships + .FirstOrDefaultAsync(m => m.CourseId == id && m.UserId == userId, cancellationToken); + + if (membership is null) + return NotFound(); + + db.CourseMemberships.Remove(membership); + await db.SaveChangesAsync(cancellationToken); + return NoContent(); + } + + // ---- CI callback tokens ---- + + [HttpGet("{id:int}/tokens")] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + public async Task>> ListTokens(int id, CancellationToken cancellationToken) + { + var tokens = await webhookTokens.ListForCourseAsync(id, cancellationToken); + return Ok(tokens.Select(t => ToDto(t, includeSecret: false)).ToList()); + } + + /// Issues a token. The response is the only place its secret appears. + [HttpPost("{id:int}/tokens")] + [ProducesResponseType(typeof(WebhookTokenDto), StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> CreateToken(int id, [FromBody] CreateWebhookTokenRequest request, CancellationToken cancellationToken) + { + if (!await db.Courses.AnyAsync(c => c.Id == id, cancellationToken)) + return NotFound(); + + var token = await webhookTokens.CreateAsync(id, Trimmed(request.Description), cancellationToken); + return CreatedAtAction(nameof(ListTokens), new { id }, ToDto(token, includeSecret: true)); + } + + [HttpDelete("{id:int}/tokens/{tokenId:int}")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task RevokeToken(int id, int tokenId, CancellationToken cancellationToken) => + await webhookTokens.RevokeAsync(id, tokenId, cancellationToken) ? NoContent() : NotFound(); + + /// + /// Applies the credential update rule: null leaves the stored value alone, empty clears it, anything else + /// replaces it. The UI sends null for a field the admin did not type into, so an unchanged form never + /// wipes a secret it was never shown. + /// + private static string? ApplySecret(string? current, string? incoming) => incoming switch + { + null => current, + "" => null, + _ => incoming.Trim(), + }; + + private static string? Trimmed(string? value) => string.IsNullOrWhiteSpace(value) ? null : value.Trim(); + + private static CourseGitHubConfigDto ToDto(CourseGitHubConfig? config) => new() + { + GitHubAppId = config?.GitHubAppId, + HasAppPrivateKey = !string.IsNullOrEmpty(config?.GitHubAppPrivateKey), + HasAccessToken = !string.IsNullOrEmpty(config?.GitHubAccessToken), + AccessTokenHint = Hint(config?.GitHubAccessToken), + HasWebhookSecret = !string.IsNullOrEmpty(config?.GitHubWebhookSecret), + WorkflowRunThreshold = config?.WorkflowRunThreshold ?? 5, + Enabled = config?.Enabled ?? false, + UpdatedAt = config?.UpdatedAt, + }; + + /// Last four characters of a secret — enough to recognize which one is stored, not enough to use. + private static string? Hint(string? secret) => + string.IsNullOrEmpty(secret) || secret.Length < 8 ? null : secret[^4..]; + + private static WebhookTokenDto ToDto(CourseWebhookToken token, bool includeSecret) => new() { - Id = c.Id, - Slug = c.Slug, - Name = c.Name, - GitHubOrganization = c.GitHubOrganization, - CreatedAt = c.CreatedAt, + Id = token.Id, + Token = token.Token, + Secret = includeSecret ? token.Secret : null, + Description = token.Description, + CreatedAt = token.CreatedAt, + RevokedAt = token.RevokedAt, }; } diff --git a/ahk-backend/Ahk.Web.Server/Admin/Dto/CourseDto.cs b/ahk-backend/Ahk.Web.Server/Admin/Dto/CourseDto.cs index 6ca6e074..c925f25f 100644 --- a/ahk-backend/Ahk.Web.Server/Admin/Dto/CourseDto.cs +++ b/ahk-backend/Ahk.Web.Server/Admin/Dto/CourseDto.cs @@ -1,10 +1,12 @@ using System.ComponentModel.DataAnnotations; +using Ahk.Web.Data.Entities; namespace Ahk.Web.Server.Admin.Dto; +/// A course as it appears in the admin list: identity plus enough counts to judge it at a glance. public sealed class CourseDto { - public Guid Id { get; set; } + public int Id { get; set; } public string Slug { get; set; } = string.Empty; @@ -12,7 +14,44 @@ public sealed class CourseDto public string? GitHubOrganization { get; set; } + public string? RepoNamePrefix { get; set; } + public DateTimeOffset CreatedAt { get; set; } + + /// False when the course's GitHub integration is switched off (or not created yet). + public bool IntegrationEnabled { get; set; } + + public int MemberCount { get; set; } + + public int StudentCount { get; set; } + + public int SubmissionCount { get; set; } +} + +/// Everything one course holds, for the course editor: settings, integration, members and tokens. +public sealed class CourseDetailDto +{ + public int Id { get; set; } + + public string Slug { get; set; } = string.Empty; + + public string Name { get; set; } = string.Empty; + + public string? GitHubOrganization { get; set; } + + public string? RepoNamePrefix { get; set; } + + public DateTimeOffset CreatedAt { get; set; } + + public int StudentCount { get; set; } + + public int SubmissionCount { get; set; } + + public CourseGitHubConfigDto GitHubConfig { get; set; } = new(); + + public IReadOnlyList Members { get; set; } = Array.Empty(); + + public IReadOnlyList WebhookTokens { get; set; } = Array.Empty(); } public sealed class CreateCourseRequest @@ -25,5 +64,124 @@ public sealed class CreateCourseRequest [MaxLength(256)] public string Name { get; set; } = string.Empty; + [MaxLength(256)] + public string? GitHubOrganization { get; set; } + + [MaxLength(256)] + public string? RepoNamePrefix { get; set; } +} + +/// +/// Course settings. The slug is included because it is editable, but changing it changes every URL the course +/// is reachable at — the UI warns before saving. +/// +public sealed class UpdateCourseRequest +{ + [Required] + [RegularExpression("^[a-z0-9-]{2,64}$", ErrorMessage = "Slug must be 2-64 chars: lowercase letters, digits, hyphen.")] + public string Slug { get; set; } = string.Empty; + + [Required] + [MaxLength(256)] + public string Name { get; set; } = string.Empty; + + [MaxLength(256)] public string? GitHubOrganization { get; set; } + + [MaxLength(256)] + public string? RepoNamePrefix { get; set; } +} + +/// +/// The course's GitHub integration as the admin UI sees it. Stored credentials are never sent back — only +/// whether one is present, and a last-four hint so an admin can tell which token is in place. +/// +public sealed class CourseGitHubConfigDto +{ + public string? GitHubAppId { get; set; } + + public bool HasAppPrivateKey { get; set; } + + public bool HasAccessToken { get; set; } + + /// Last four characters of the stored access token, e.g. "…f3Ab". Null when none is stored. + public string? AccessTokenHint { get; set; } + + public bool HasWebhookSecret { get; set; } + + public int WorkflowRunThreshold { get; set; } + + public bool Enabled { get; set; } + + public DateTimeOffset? UpdatedAt { get; set; } +} + +/// +/// Update for the GitHub integration. The three credential fields follow one rule: null leaves the +/// stored value alone (the UI sends null when the admin did not touch the field), an empty string clears it, +/// and any other value replaces it. +/// +public sealed class UpdateCourseGitHubConfigRequest +{ + [MaxLength(64)] + public string? GitHubAppId { get; set; } + + public string? GitHubAppPrivateKey { get; set; } + + [MaxLength(512)] + public string? GitHubAccessToken { get; set; } + + [MaxLength(512)] + public string? GitHubWebhookSecret { get; set; } + + [Range(1, 1000)] + public int WorkflowRunThreshold { get; set; } = 5; + + public bool Enabled { get; set; } = true; +} + +public sealed class CourseMemberDto +{ + public int UserId { get; set; } + + public string UserName { get; set; } = string.Empty; + + public string? DisplayName { get; set; } + + public string? Email { get; set; } + + public CourseRole Role { get; set; } +} + +public sealed class UpsertCourseMemberRequest +{ + [Required] + public int UserId { get; set; } + + public CourseRole Role { get; set; } = CourseRole.Instructor; +} + +/// +/// A CI callback token. is populated only in the response that creates the token — it is +/// never readable afterwards, so the UI shows it once and tells the admin to copy it. +/// +public sealed class WebhookTokenDto +{ + public int Id { get; set; } + + public string Token { get; set; } = string.Empty; + + public string? Secret { get; set; } + + public string? Description { get; set; } + + public DateTimeOffset CreatedAt { get; set; } + + public DateTimeOffset? RevokedAt { get; set; } +} + +public sealed class CreateWebhookTokenRequest +{ + [MaxLength(512)] + public string? Description { get; set; } } diff --git a/ahk-backend/Ahk.Web.Server/Admin/Dto/UserDto.cs b/ahk-backend/Ahk.Web.Server/Admin/Dto/UserDto.cs new file mode 100644 index 00000000..82acc80a --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Admin/Dto/UserDto.cs @@ -0,0 +1,103 @@ +using System.ComponentModel.DataAnnotations; +using Ahk.Web.Data.Entities; + +namespace Ahk.Web.Server.Admin.Dto; + +/// A registered user with the two things an admin edits: site roles and course assignments. +public sealed class UserDto +{ + public int Id { get; set; } + + public string UserName { get; set; } = string.Empty; + + public string? Email { get; set; } + + public string? DisplayName { get; set; } + + /// From the IdP's neptun_code claim; empty for local accounts. + public string? NeptunCode { get; set; } + + /// From the IdP's eduperson_scoped_affiliation claim, values joined with ';'. + public string? Affiliation { get; set; } + + public IReadOnlyList Roles { get; set; } = Array.Empty(); + + public IReadOnlyList Courses { get; set; } = Array.Empty(); + + /// True when the account signs in through the identity provider rather than a local password. + public bool IsExternal { get; set; } + + /// True while the account is locked out, so the list can show why a sign-in is failing. + public bool IsLockedOut { get; set; } +} + +public sealed class UserCourseDto +{ + public int CourseId { get; set; } + + public string Slug { get; set; } = string.Empty; + + public string Name { get; set; } = string.Empty; + + public CourseRole Role { get; set; } +} + +/// One page of users, plus the total so the UI can say "showing 25 of 340". +public sealed class UserListResponse +{ + public IReadOnlyList Items { get; set; } = Array.Empty(); + + public int Total { get; set; } +} + +public sealed class CreateUserRequest +{ + [Required] + [MaxLength(256)] + public string UserName { get; set; } = string.Empty; + + [EmailAddress] + [MaxLength(256)] + public string? Email { get; set; } + + [MaxLength(256)] + public string? DisplayName { get; set; } + + [Required] + [MinLength(6)] + public string Password { get; set; } = string.Empty; +} + +public sealed class UpdateUserRequest +{ + [EmailAddress] + [MaxLength(256)] + public string? Email { get; set; } + + [MaxLength(256)] + public string? DisplayName { get; set; } + + [MaxLength(32)] + public string? NeptunCode { get; set; } +} + +/// The complete set of site roles the user should hold; anything not listed is removed. +public sealed class UpdateUserRolesRequest +{ + public IReadOnlyList Roles { get; set; } = Array.Empty(); +} + +public sealed class UpsertUserCourseRequest +{ + [Required] + public int CourseId { get; set; } + + public CourseRole Role { get; set; } = CourseRole.Instructor; +} + +public sealed class SetPasswordRequest +{ + [Required] + [MinLength(6)] + public string NewPassword { get; set; } = string.Empty; +} diff --git a/ahk-backend/Ahk.Web.Server/Admin/UsersAdminController.cs b/ahk-backend/Ahk.Web.Server/Admin/UsersAdminController.cs new file mode 100644 index 00000000..478f88c7 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Admin/UsersAdminController.cs @@ -0,0 +1,310 @@ +using System.Globalization; +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Ahk.Web.Server.Admin.Dto; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace Ahk.Web.Server.Admin; + +/// +/// Host/admin context: who has an account, what site role they hold, and which courses they are assigned to. +/// Site roles come from ASP.NET Identity (); course assignments are +/// rows, which is what the CourseMember policy reads. +/// +/// Two self-inflicted lockouts are refused: an admin cannot drop their own Admin role, and cannot delete +/// their own account. +/// +[ApiController] +[Route("api/admin/users")] +[Authorize(Roles = Roles.Admin)] +public sealed class UsersAdminController : ControllerBase +{ + private const int MaxPageSize = 200; + + private readonly ApplicationDbContext db; + private readonly UserManager userManager; + + public UsersAdminController(ApplicationDbContext db, UserManager userManager) + { + this.db = db; + this.userManager = userManager; + } + + /// + /// Lists users, newest account last. matches user name, display name, e-mail or + /// Neptun code; narrows to the members of one course. + /// + [HttpGet] + [ProducesResponseType(typeof(UserListResponse), StatusCodes.Status200OK)] + public async Task> List( + [FromQuery] string? search, + [FromQuery] int? courseId, + [FromQuery] int skip = 0, + [FromQuery] int take = 50, + CancellationToken cancellationToken = default) + { + var query = db.Users.AsNoTracking(); + + if (!string.IsNullOrWhiteSpace(search)) + { + var term = search.Trim(); + query = query.Where(u => + (u.UserName != null && u.UserName.Contains(term)) || + (u.DisplayName != null && u.DisplayName.Contains(term)) || + (u.Email != null && u.Email.Contains(term)) || + (u.NeptunCode != null && u.NeptunCode.Contains(term))); + } + + if (courseId is int id) + query = query.Where(u => u.CourseMemberships.Any(m => m.CourseId == id)); + + var total = await query.CountAsync(cancellationToken); + + var users = await query + .OrderBy(u => u.UserName) + .Skip(Math.Max(0, skip)) + .Take(Math.Clamp(take, 1, MaxPageSize)) + .Select(u => new + { + User = u, + Courses = u.CourseMemberships + .Select(m => new UserCourseDto { CourseId = m.CourseId, Slug = m.Course!.Slug, Name = m.Course.Name, Role = m.Role }) + .ToList(), + }) + .ToListAsync(cancellationToken); + + // Roles come from Identity's join tables; one query for the page beats one per user. + var userIds = users.Select(u => u.User.Id).ToList(); + var rolesByUser = await db.UserRoles + .AsNoTracking() + .Where(ur => userIds.Contains(ur.UserId)) + .Join(db.Roles, ur => ur.RoleId, r => r.Id, (ur, r) => new { ur.UserId, RoleName = r.Name! }) + .ToListAsync(cancellationToken); + + var items = users.Select(u => ToDto( + u.User, + rolesByUser.Where(r => r.UserId == u.User.Id).Select(r => r.RoleName).OrderBy(r => r, StringComparer.Ordinal).ToList(), + u.Courses.OrderBy(c => c.Slug, StringComparer.Ordinal).ToList())) + .ToList(); + + return Ok(new UserListResponse { Items = items, Total = total }); + } + + [HttpGet("{id:int}")] + [ProducesResponseType(typeof(UserDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> Get(int id, CancellationToken cancellationToken) + { + var user = await db.Users.AsNoTracking().FirstOrDefaultAsync(u => u.Id == id, cancellationToken); + return user is null ? NotFound() : Ok(await LoadDtoAsync(user, cancellationToken)); + } + + /// Creates a local (password) account. Directory users are created on their first OIDC sign-in. + [HttpPost] + [ProducesResponseType(typeof(UserDto), StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public async Task> Create([FromBody] CreateUserRequest request, CancellationToken cancellationToken) + { + var user = new ApplicationUser + { + UserName = request.UserName.Trim(), + Email = string.IsNullOrWhiteSpace(request.Email) ? null : request.Email.Trim(), + DisplayName = string.IsNullOrWhiteSpace(request.DisplayName) ? null : request.DisplayName.Trim(), + EmailConfirmed = true, + }; + + var result = await userManager.CreateAsync(user, request.Password); + if (!result.Succeeded) + return BadRequest(new { errors = result.Errors.Select(e => e.Description) }); + + return CreatedAtAction(nameof(Get), new { id = user.Id }, await LoadDtoAsync(user, cancellationToken)); + } + + [HttpPut("{id:int}")] + [ProducesResponseType(typeof(UserDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> Update(int id, [FromBody] UpdateUserRequest request, CancellationToken cancellationToken) + { + var user = await userManager.FindByIdAsync(id.ToString(CultureInfo.InvariantCulture)); + if (user is null) + return NotFound(); + + user.DisplayName = Trimmed(request.DisplayName); + user.NeptunCode = request.NeptunCode is null ? null : Normalize.Neptun(request.NeptunCode); + + var email = Trimmed(request.Email); + if (!string.Equals(user.Email, email, StringComparison.OrdinalIgnoreCase)) + { + var emailResult = await userManager.SetEmailAsync(user, email); + if (!emailResult.Succeeded) + return BadRequest(new { errors = emailResult.Errors.Select(e => e.Description) }); + } + + var result = await userManager.UpdateAsync(user); + if (!result.Succeeded) + return BadRequest(new { errors = result.Errors.Select(e => e.Description) }); + + return Ok(await LoadDtoAsync(user, cancellationToken)); + } + + /// Replaces the user's site roles with exactly the set given. + [HttpPut("{id:int}/roles")] + [ProducesResponseType(typeof(UserDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> UpdateRoles(int id, [FromBody] UpdateUserRolesRequest request, CancellationToken cancellationToken) + { + var user = await userManager.FindByIdAsync(id.ToString(CultureInfo.InvariantCulture)); + if (user is null) + return NotFound(); + + var requested = request.Roles.Select(r => r.Trim()).Where(r => r.Length > 0).Distinct(StringComparer.Ordinal).ToList(); + + var unknown = requested.Where(r => !Roles.All.Contains(r, StringComparer.Ordinal)).ToList(); + if (unknown.Count > 0) + return BadRequest(new { error = $"Unknown role: {string.Join(", ", unknown)}." }); + + if (IsSelf(user) && !requested.Contains(Roles.Admin, StringComparer.Ordinal)) + return BadRequest(new { error = "You cannot remove your own Admin role. Ask another administrator to do it." }); + + var current = await userManager.GetRolesAsync(user); + + var toRemove = current.Except(requested, StringComparer.Ordinal).ToList(); + if (toRemove.Count > 0) + { + var removeResult = await userManager.RemoveFromRolesAsync(user, toRemove); + if (!removeResult.Succeeded) + return BadRequest(new { errors = removeResult.Errors.Select(e => e.Description) }); + } + + var toAdd = requested.Except(current, StringComparer.Ordinal).ToList(); + if (toAdd.Count > 0) + { + var addResult = await userManager.AddToRolesAsync(user, toAdd); + if (!addResult.Succeeded) + return BadRequest(new { errors = addResult.Errors.Select(e => e.Description) }); + } + + return Ok(await LoadDtoAsync(user, cancellationToken)); + } + + /// Assigns the user to a course, or changes the role they hold in it. + [HttpPut("{id:int}/courses")] + [ProducesResponseType(typeof(UserDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> UpsertCourse(int id, [FromBody] UpsertUserCourseRequest request, CancellationToken cancellationToken) + { + var user = await db.Users.FirstOrDefaultAsync(u => u.Id == id, cancellationToken); + if (user is null) + return NotFound(); + + if (!await db.Courses.AnyAsync(c => c.Id == request.CourseId, cancellationToken)) + return NotFound(new { error = "No such course." }); + + var membership = await db.CourseMemberships + .FirstOrDefaultAsync(m => m.UserId == id && m.CourseId == request.CourseId, cancellationToken); + + if (membership is null) + db.CourseMemberships.Add(new CourseMembership { UserId = id, CourseId = request.CourseId, Role = request.Role }); + else + membership.Role = request.Role; + + await db.SaveChangesAsync(cancellationToken); + return Ok(await LoadDtoAsync(user, cancellationToken)); + } + + [HttpDelete("{id:int}/courses/{courseId:int}")] + [ProducesResponseType(typeof(UserDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> RemoveCourse(int id, int courseId, CancellationToken cancellationToken) + { + var user = await db.Users.FirstOrDefaultAsync(u => u.Id == id, cancellationToken); + if (user is null) + return NotFound(); + + var membership = await db.CourseMemberships + .FirstOrDefaultAsync(m => m.UserId == id && m.CourseId == courseId, cancellationToken); + + if (membership is not null) + { + db.CourseMemberships.Remove(membership); + await db.SaveChangesAsync(cancellationToken); + } + + return Ok(await LoadDtoAsync(user, cancellationToken)); + } + + /// Sets a new password for a local account, e.g. after a support request. + [HttpPost("{id:int}/password")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task SetPassword(int id, [FromBody] SetPasswordRequest request) + { + var user = await userManager.FindByIdAsync(id.ToString(CultureInfo.InvariantCulture)); + if (user is null) + return NotFound(); + + var token = await userManager.GeneratePasswordResetTokenAsync(user); + var result = await userManager.ResetPasswordAsync(user, token, request.NewPassword); + + return result.Succeeded + ? NoContent() + : BadRequest(new { errors = result.Errors.Select(e => e.Description) }); + } + + [HttpDelete("{id:int}")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task Delete(int id) + { + var user = await userManager.FindByIdAsync(id.ToString(CultureInfo.InvariantCulture)); + if (user is null) + return NotFound(); + + if (IsSelf(user)) + return BadRequest(new { error = "You cannot delete your own account." }); + + var result = await userManager.DeleteAsync(user); + return result.Succeeded + ? NoContent() + : BadRequest(new { errors = result.Errors.Select(e => e.Description) }); + } + + private bool IsSelf(ApplicationUser user) => + string.Equals(userManager.GetUserId(User), user.Id.ToString(CultureInfo.InvariantCulture), StringComparison.Ordinal); + + private async Task LoadDtoAsync(ApplicationUser user, CancellationToken cancellationToken) + { + var roles = await userManager.GetRolesAsync(user); + var courses = await db.CourseMemberships + .AsNoTracking() + .Where(m => m.UserId == user.Id) + .OrderBy(m => m.Course!.Slug) + .Select(m => new UserCourseDto { CourseId = m.CourseId, Slug = m.Course!.Slug, Name = m.Course.Name, Role = m.Role }) + .ToListAsync(cancellationToken); + + return ToDto(user, roles.OrderBy(r => r, StringComparer.Ordinal).ToList(), courses); + } + + private static UserDto ToDto(ApplicationUser user, IReadOnlyList roles, IReadOnlyList courses) => new() + { + Id = user.Id, + UserName = user.UserName ?? string.Empty, + Email = user.Email, + DisplayName = user.DisplayName, + NeptunCode = user.NeptunCode, + Affiliation = user.Affiliation, + Roles = roles, + Courses = courses, + IsExternal = user.PasswordHash is null, + IsLockedOut = user.LockoutEnd is not null && user.LockoutEnd > DateTimeOffset.UtcNow, + }; + + private static string? Trimmed(string? value) => string.IsNullOrWhiteSpace(value) ? null : value.Trim(); +} diff --git a/ahk-backend/Ahk.Web.Server/Ahk.Web.Server.csproj b/ahk-backend/Ahk.Web.Server/Ahk.Web.Server.csproj index 73169844..6da6e842 100644 --- a/ahk-backend/Ahk.Web.Server/Ahk.Web.Server.csproj +++ b/ahk-backend/Ahk.Web.Server/Ahk.Web.Server.csproj @@ -17,6 +17,7 @@ + diff --git a/ahk-backend/Ahk.Web.Server/Auth/AuthController.cs b/ahk-backend/Ahk.Web.Server/Auth/AuthController.cs index e04c15ee..f28b7911 100644 --- a/ahk-backend/Ahk.Web.Server/Auth/AuthController.cs +++ b/ahk-backend/Ahk.Web.Server/Auth/AuthController.cs @@ -1,10 +1,12 @@ using Ahk.Web.Data; using Ahk.Web.Data.Entities; using Ahk.Web.Server.Auth.Dto; +using Ahk.Web.Server.Configuration; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; namespace Ahk.Web.Server.Auth; @@ -16,34 +18,82 @@ public sealed class AuthController : ControllerBase private readonly SignInManager signInManager; private readonly UserManager userManager; private readonly ApplicationDbContext db; + private readonly OidcOptions oidcOptions; - public AuthController(SignInManager signInManager, UserManager userManager, ApplicationDbContext db) + public AuthController( + SignInManager signInManager, + UserManager userManager, + ApplicationDbContext db, + IOptions oidcOptions) { this.signInManager = signInManager; this.userManager = userManager; this.db = db; + this.oidcOptions = oidcOptions.Value; } [HttpPost("login")] [ProducesResponseType(typeof(CurrentUserResponse), StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(typeof(LoginFailureResponse), StatusCodes.Status401Unauthorized)] public async Task> Login([FromBody] LoginRequest request) { var result = await signInManager.PasswordSignInAsync(request.UserName, request.Password, request.RememberMe, lockoutOnFailure: true); + + // Lockout and a wrong password share the 401, but they need different words: one is "try again", + // the other is "wait, or ask an administrator". + if (result.IsLockedOut) + { + return Unauthorized(new LoginFailureResponse + { + Reason = "LockedOut", + Error = "This account is temporarily locked after too many failed attempts. Try again in a few minutes.", + }); + } + + if (result.IsNotAllowed) + { + return Unauthorized(new LoginFailureResponse + { + Reason = "NotAllowed", + Error = "This account is not allowed to sign in. Ask an administrator to check it.", + }); + } + if (!result.Succeeded) - return Unauthorized(); + { + return Unauthorized(new LoginFailureResponse + { + Reason = "InvalidCredentials", + Error = "That username and password do not match an account.", + }); + } var user = await userManager.FindByNameAsync(request.UserName); return Ok(await BuildCurrentUserAsync(user!)); } + /// + /// Clears the portal session. Returns the provider's end-session URL when one is configured, which the SPA + /// then navigates to; the BME IdP does not advertise end_session_endpoint, so today this is null and + /// sign-out is local-only (the SSO session at the IdP survives). + /// [HttpPost("logout")] [Authorize] - [ProducesResponseType(StatusCodes.Status204NoContent)] - public async Task Logout() + [ProducesResponseType(typeof(LogoutResponse), StatusCodes.Status200OK)] + public async Task> Logout() { await signInManager.SignOutAsync(); - return NoContent(); + + var endSession = oidcOptions.EndSessionEndpoint; + if (string.IsNullOrWhiteSpace(endSession)) + return Ok(new LogoutResponse { EndSessionUrl = null }); + + var postLogout = oidcOptions.PostLogoutRedirectUri; + var url = string.IsNullOrWhiteSpace(postLogout) + ? endSession + : $"{endSession}{(endSession.Contains('?', StringComparison.Ordinal) ? "&" : "?")}post_logout_redirect_uri={Uri.EscapeDataString(postLogout)}"; + + return Ok(new LogoutResponse { EndSessionUrl = url }); } [HttpPost("register")] @@ -76,7 +126,8 @@ public async Task> Me() private async Task BuildCurrentUserAsync(ApplicationUser user) { var roles = await userManager.GetRolesAsync(user); - var courses = await db.CourseMemberships + + var memberships = await db.CourseMemberships .AsNoTracking() .Where(m => m.UserId == user.Id) .Select(m => new CourseMembershipDto @@ -87,6 +138,29 @@ private async Task BuildCurrentUserAsync(ApplicationUser us }) .ToListAsync(); + // A site admin may open any course (CourseMembershipAuthorizationHandler says so), so the switcher has + // to list them all — otherwise the instructor screens are unreachable for courses they do not staff. + // Explicit memberships win, keeping the role the admin actually holds in their own courses. + var courses = memberships; + if (roles.Contains(Roles.Admin, StringComparer.Ordinal)) + { + var assigned = memberships.Select(m => m.Slug).ToHashSet(StringComparer.Ordinal); + var rest = await db.Courses + .AsNoTracking() + .Where(c => !assigned.Contains(c.Slug)) + .OrderBy(c => c.Slug) + .Select(c => new CourseMembershipDto + { + Slug = c.Slug, + Name = c.Name, + Role = CourseRole.Admin.ToString(), + ViaSiteAdmin = true, + }) + .ToListAsync(); + + courses = memberships.Concat(rest).OrderBy(c => c.Slug, StringComparer.Ordinal).ToList(); + } + return new CurrentUserResponse { UserId = user.Id, diff --git a/ahk-backend/Ahk.Web.Server/Auth/BmeClaimTypes.cs b/ahk-backend/Ahk.Web.Server/Auth/BmeClaimTypes.cs new file mode 100644 index 00000000..f6ebe3b4 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Auth/BmeClaimTypes.cs @@ -0,0 +1,14 @@ +namespace Ahk.Web.Server.Auth; + +/// +/// Claim names published by the BME IdP (see its claims_supported). Used both for the OIDC claim +/// mappings and when syncing an external identity onto the local user. +/// +public static class BmeClaimTypes +{ + /// Student/staff Neptun code — the key of the domain model. + public const string NeptunCode = "neptun_code"; + + /// Multi-valued, e.g. ["staff@bme.hu", "employee@bme.hu"]. + public const string Affiliation = "eduperson_scoped_affiliation"; +} diff --git a/ahk-backend/Ahk.Web.Server/Auth/Dto/CurrentUserResponse.cs b/ahk-backend/Ahk.Web.Server/Auth/Dto/CurrentUserResponse.cs index 8db6a4ab..092d9f82 100644 --- a/ahk-backend/Ahk.Web.Server/Auth/Dto/CurrentUserResponse.cs +++ b/ahk-backend/Ahk.Web.Server/Auth/Dto/CurrentUserResponse.cs @@ -3,7 +3,7 @@ namespace Ahk.Web.Server.Auth.Dto; /// Shape returned by GET /api/auth/me — hydrates the SPA session with identity + course access. public sealed class CurrentUserResponse { - public string UserId { get; set; } = string.Empty; + public int UserId { get; set; } public string UserName { get; set; } = string.Empty; @@ -13,6 +13,10 @@ public sealed class CurrentUserResponse public IReadOnlyList Roles { get; set; } = Array.Empty(); + /// + /// Every course this user can open, which is what the course switcher lists. For a site admin that is all + /// courses, matching CourseMembershipAuthorizationHandler, which lets admins into any course. + /// public IReadOnlyList Courses { get; set; } = Array.Empty(); } @@ -23,4 +27,10 @@ public sealed class CourseMembershipDto public string Name { get; set; } = string.Empty; public string Role { get; set; } = string.Empty; + + /// + /// True when access comes from the site-admin role rather than a membership record. The UI marks these so + /// an admin can see they are working inside a course they were not explicitly assigned to. + /// + public bool ViaSiteAdmin { get; set; } } diff --git a/ahk-backend/Ahk.Web.Server/Auth/Dto/LoginRequest.cs b/ahk-backend/Ahk.Web.Server/Auth/Dto/LoginRequest.cs index 2a18bd16..ba5e20c3 100644 --- a/ahk-backend/Ahk.Web.Server/Auth/Dto/LoginRequest.cs +++ b/ahk-backend/Ahk.Web.Server/Auth/Dto/LoginRequest.cs @@ -12,3 +12,16 @@ public sealed class LoginRequest public bool RememberMe { get; set; } } + +/// +/// Why a sign-in was refused. Sent with the 401 so the SPA can say what actually happened — a locked-out +/// account and a mistyped password are the same status code but very different things to be told. +/// +public sealed class LoginFailureResponse +{ + /// Machine-readable: InvalidCredentials, LockedOut or NotAllowed. + public string Reason { get; set; } = string.Empty; + + /// Sentence shown to the person signing in. + public string Error { get; set; } = string.Empty; +} diff --git a/ahk-backend/Ahk.Web.Server/Auth/Dto/LogoutResponse.cs b/ahk-backend/Ahk.Web.Server/Auth/Dto/LogoutResponse.cs new file mode 100644 index 00000000..886a0bc0 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Auth/Dto/LogoutResponse.cs @@ -0,0 +1,11 @@ +namespace Ahk.Web.Server.Auth.Dto; + +/// Result of signing out of the portal. +public sealed class LogoutResponse +{ + /// + /// Provider end-session URL the SPA should navigate to for a full single sign-out, or null when the + /// provider has none configured (the current case for the BME IdP) and sign-out is local-only. + /// + public string? EndSessionUrl { get; set; } +} diff --git a/ahk-backend/Ahk.Web.Server/Auth/ExternalAuthController.cs b/ahk-backend/Ahk.Web.Server/Auth/ExternalAuthController.cs index 7a211acf..6c2c8a43 100644 --- a/ahk-backend/Ahk.Web.Server/Auth/ExternalAuthController.cs +++ b/ahk-backend/Ahk.Web.Server/Auth/ExternalAuthController.cs @@ -2,6 +2,7 @@ using Ahk.Web.Data.Entities; using Ahk.Web.Server.Configuration; using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; @@ -23,12 +24,18 @@ public sealed class ExternalAuthController : ControllerBase private readonly SignInManager signInManager; private readonly UserManager userManager; private readonly OidcOptions oidcOptions; + private readonly ILogger logger; - public ExternalAuthController(SignInManager signInManager, UserManager userManager, IOptions oidcOptions) + public ExternalAuthController( + SignInManager signInManager, + UserManager userManager, + IOptions oidcOptions, + ILogger logger) { this.signInManager = signInManager; this.userManager = userManager; this.oidcOptions = oidcOptions.Value; + this.logger = logger; } [HttpGet("challenge")] @@ -50,29 +57,71 @@ public async Task Callback([FromQuery] string? returnUrl) return Redirect(SafeReturnUrl(returnUrl, error: "external_login_failed")); var signInResult = await signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: true, bypassTwoFactor: true); - if (!signInResult.Succeeded) + if (signInResult.Succeeded) { - // First time this external identity is seen: provision a local user and link the login. - var email = info.Principal.FindFirstValue(ClaimTypes.Email); - var name = info.Principal.FindFirstValue(ClaimTypes.Name) ?? email ?? info.ProviderKey; + // Known identity: refresh the directory data, which may have changed since the last login. + var existing = await userManager.FindByLoginAsync(info.LoginProvider, info.ProviderKey); + if (existing is not null && ExternalClaimsMapper.SyncFromClaims(existing, info.Principal)) + await userManager.UpdateAsync(existing); - var user = (email is not null ? await userManager.FindByEmailAsync(email) : null) - ?? new ApplicationUser { UserName = email ?? $"{info.LoginProvider}:{info.ProviderKey}", Email = email, DisplayName = name, EmailConfirmed = true }; + return Redirect(SafeReturnUrl(returnUrl)); + } + + // First time this external identity is seen: provision a local user and link the login. + var email = info.Principal.FindFirstValue(ClaimTypes.Email); + + var user = (email is not null ? await userManager.FindByEmailAsync(email) : null) + ?? new ApplicationUser { UserName = email ?? BuildUserName(info), EmailConfirmed = true }; + + ExternalClaimsMapper.SyncFromClaims(user, info.Principal); - if (user.Id.Length == 0 || await userManager.FindByIdAsync(user.Id) is null) + // Id is 0 until the row is inserted, so this distinguishes a brand-new user from one found by email. + if (user.Id == 0) + { + var created = await userManager.CreateAsync(user); + if (!created.Succeeded) { - var created = await userManager.CreateAsync(user); - if (!created.Succeeded) - return Redirect(SafeReturnUrl(returnUrl, error: "user_creation_failed")); - } + logger.LogError( + "Provisioning a user for external login {Provider}/{ProviderKey} failed: {Errors}", + info.LoginProvider, + info.ProviderKey, + string.Join("; ", created.Errors.Select(e => $"{e.Code}: {e.Description}"))); - await userManager.AddLoginAsync(user, info); - await signInManager.SignInAsync(user, isPersistent: true); + return Redirect(SafeReturnUrl(returnUrl, error: "user_creation_failed")); + } + } + else + { + await userManager.UpdateAsync(user); } + await userManager.AddLoginAsync(user, info); + await signInManager.SignInAsync(user, isPersistent: true); + return Redirect(SafeReturnUrl(returnUrl)); } + /// + /// Landing point after a provider-initiated sign-out, matching the registered + /// post_logout_redirect_uris (https://ahk.aut.bme.hu/signout-callback-oidc). Unused while the BME IdP + /// advertises no end-session endpoint, but registered and wired so enabling it needs no code change. + /// + [HttpGet("/signout-callback-oidc")] + [AllowAnonymous] + public IActionResult SignedOut([FromQuery] string? returnUrl) + => Redirect(SafeReturnUrl(returnUrl)); + + /// + /// Fallback username when the provider returns no email. Identity's AllowedUserNameCharacters excludes ':', + /// so the provider/subject pair is sanitized rather than concatenated raw. + /// + private static string BuildUserName(ExternalLoginInfo info) + { + var raw = $"{info.LoginProvider}-{info.ProviderKey}"; + var safe = new string(raw.Select(c => char.IsLetterOrDigit(c) || c is '-' or '.' or '_' or '@' or '+' ? c : '-').ToArray()); + return safe; + } + // Only allow relative return paths to avoid open-redirects; default to the SPA root. private string SafeReturnUrl(string? returnUrl, string? error = null) { diff --git a/ahk-backend/Ahk.Web.Server/Auth/ExternalClaimsMapper.cs b/ahk-backend/Ahk.Web.Server/Auth/ExternalClaimsMapper.cs new file mode 100644 index 00000000..a739aa7c --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Auth/ExternalClaimsMapper.cs @@ -0,0 +1,79 @@ +using System.Security.Claims; +using Ahk.Web.Data.Entities; + +namespace Ahk.Web.Server.Auth; + +/// +/// Projects an external (BME OIDC) identity onto the local user record. Applied on every login, not just at +/// creation, so a user's directory data stays current. +/// +public static class ExternalClaimsMapper +{ + /// Copies the mapped claims onto . Returns true when anything changed. + public static bool SyncFromClaims(ApplicationUser user, ClaimsPrincipal principal) + { + ArgumentNullException.ThrowIfNull(user); + ArgumentNullException.ThrowIfNull(principal); + + var changed = false; + + var email = principal.FindFirstValue(ClaimTypes.Email); + if (!string.IsNullOrWhiteSpace(email) && !string.Equals(user.Email, email, StringComparison.OrdinalIgnoreCase)) + { + user.Email = email; + changed = true; + } + + var displayName = ResolveDisplayName(principal); + if (!string.IsNullOrWhiteSpace(displayName) && !string.Equals(user.DisplayName, displayName, StringComparison.Ordinal)) + { + user.DisplayName = displayName; + changed = true; + } + + // Absent claims must not wipe existing values — a sparse directory account should not clear a known code. + var neptun = principal.FindFirstValue(BmeClaimTypes.NeptunCode); + if (!string.IsNullOrWhiteSpace(neptun) && !string.Equals(user.NeptunCode, neptun, StringComparison.OrdinalIgnoreCase)) + { + user.NeptunCode = neptun.ToUpperInvariant(); + changed = true; + } + + var affiliation = ResolveAffiliation(principal); + if (!string.IsNullOrWhiteSpace(affiliation) && !string.Equals(user.Affiliation, affiliation, StringComparison.Ordinal)) + { + user.Affiliation = affiliation; + changed = true; + } + + return changed; + } + + /// Prefers the provider's name, otherwise composes it from given/family name. + public static string? ResolveDisplayName(ClaimsPrincipal principal) + { + var name = principal.FindFirstValue(ClaimTypes.Name) ?? principal.FindFirstValue("name"); + if (!string.IsNullOrWhiteSpace(name)) + return name; + + var given = principal.FindFirstValue(ClaimTypes.GivenName) ?? principal.FindFirstValue("given_name"); + var family = principal.FindFirstValue(ClaimTypes.Surname) ?? principal.FindFirstValue("family_name"); + var composed = string.Join(' ', new[] { given, family }.Where(s => !string.IsNullOrWhiteSpace(s))); + + return string.IsNullOrWhiteSpace(composed) ? null : composed; + } + + /// + /// eduperson_scoped_affiliation is multi-valued. The claim action joins array values, but a provider may + /// also emit repeated claims — handle both and normalize to a single ';'-separated string. + /// + public static string? ResolveAffiliation(ClaimsPrincipal principal) + { + var values = principal.FindAll(BmeClaimTypes.Affiliation) + .SelectMany(c => c.Value.Split(';', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToArray(); + + return values.Length == 0 ? null : string.Join(';', values); + } +} diff --git a/ahk-backend/Ahk.Web.Server/Configuration/OidcOptions.cs b/ahk-backend/Ahk.Web.Server/Configuration/OidcOptions.cs index 43311f3d..fad76274 100644 --- a/ahk-backend/Ahk.Web.Server/Configuration/OidcOptions.cs +++ b/ahk-backend/Ahk.Web.Server/Configuration/OidcOptions.cs @@ -1,9 +1,11 @@ namespace Ahk.Web.Server.Configuration; /// -/// Generic OpenID Connect provider settings (bound from configuration section Authentication:Oidc). -/// When is empty the external login handler is not registered and OIDC is disabled, -/// so the app runs with local username/password only. +/// OpenID Connect provider settings (configuration section Authentication:Oidc). Written against BME's +/// Shibboleth IdP (https://idp.bme.hu) but kept generic. +/// +/// When / are empty the external login handler is not registered +/// and OIDC is disabled, so the app runs with local username/password only. /// public sealed class OidcOptions { @@ -13,10 +15,48 @@ public sealed class OidcOptions public string? ClientId { get; set; } + /// Never commit this — use `dotnet user-secrets` locally and Authentication__Oidc__ClientSecret in production. public string? ClientSecret { get; set; } - /// Scopes to request in addition to openid/profile. Defaults to email. - public string[] Scopes { get; set; } = new[] { "email" }; + /// + /// Exact scopes to request. Must stay within what the client is registered for — requesting an + /// unregistered scope (e.g. profile, which BME did not register for us) is a common rejection cause. + /// offline_access is registered but omitted by default: we mint our own Identity cookie and never + /// use refresh tokens. + /// + public string[] Scopes { get; set; } = new[] { "openid", "email", "userinfo" }; + + /// + /// Off by default: the BME IdP does not advertise code_challenge_methods_supported, and we are a + /// confidential client (client_secret_post), so PKCE is defence-in-depth rather than required. + /// + public bool UsePkce { get; set; } + + /// + /// query by default. The ASP.NET default of form_post makes the callback a cross-site POST, + /// which drops the correlation cookie under SameSite=Lax and fails with "Correlation failed". + /// + public string ResponseMode { get; set; } = "query"; + + /// We exchange the external identity for our own cookie, so the provider's tokens are not kept. + public bool SaveTokens { get; set; } + + /// + /// Absolute redirect_uri override. Needed in development because the Angular proxy rewrites the Host, so the + /// computed value would point at the backend port instead of the browser's origin. + /// + public string? RedirectUri { get; set; } + + public string? PostLogoutRedirectUri { get; set; } + + /// + /// RP-initiated logout endpoint. The BME IdP does not advertise end_session_endpoint, so this is empty + /// and logout is local-only; setting it later enables full sign-out with no code change. + /// + public string? EndSessionEndpoint { get; set; } + + /// Development only: serve an in-app mock OpenID provider at /mock-oidc (see MockOidc/). + public bool UseMockProvider { get; set; } public bool IsEnabled => !string.IsNullOrWhiteSpace(Authority) && !string.IsNullOrWhiteSpace(ClientId); } diff --git a/ahk-backend/Ahk.Web.Server/CourseContext/CourseMembershipAuthorizationHandler.cs b/ahk-backend/Ahk.Web.Server/CourseContext/CourseMembershipAuthorizationHandler.cs index f98480a2..ff3b320b 100644 --- a/ahk-backend/Ahk.Web.Server/CourseContext/CourseMembershipAuthorizationHandler.cs +++ b/ahk-backend/Ahk.Web.Server/CourseContext/CourseMembershipAuthorizationHandler.cs @@ -25,7 +25,7 @@ public CourseMembershipAuthorizationHandler(ICurrentCourseProvider currentCourse protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, CourseMembershipRequirement requirement) { - if (currentCourse.CurrentCourseId is not Guid courseId) + if (currentCourse.CurrentCourseId is not int courseId) return; if (context.User.Identity?.IsAuthenticated != true) @@ -37,8 +37,7 @@ protected override async Task HandleRequirementAsync(AuthorizationHandlerContext return; } - var userId = userManager.GetUserId(context.User); - if (userId is null) + if (!int.TryParse(userManager.GetUserId(context.User), out var userId)) return; var isMember = await db.CourseMemberships.AsNoTracking() diff --git a/ahk-backend/Ahk.Web.Server/CourseContext/CurrentCourseProvider.cs b/ahk-backend/Ahk.Web.Server/CourseContext/CurrentCourseProvider.cs index 030d4f78..89ea2db2 100644 --- a/ahk-backend/Ahk.Web.Server/CourseContext/CurrentCourseProvider.cs +++ b/ahk-backend/Ahk.Web.Server/CourseContext/CurrentCourseProvider.cs @@ -8,7 +8,7 @@ namespace Ahk.Web.Server.CourseContext; /// public sealed class CurrentCourseProvider : ICurrentCourseProvider { - public Guid? CurrentCourseId { get; private set; } + public int? CurrentCourseId { get; private set; } - public void Set(Guid courseId) => CurrentCourseId = courseId; + public void Set(int courseId) => CurrentCourseId = courseId; } diff --git a/ahk-backend/Ahk.Web.Server/Courses/CourseProbeController.cs b/ahk-backend/Ahk.Web.Server/Courses/CourseProbeController.cs deleted file mode 100644 index 3f7267ec..00000000 --- a/ahk-backend/Ahk.Web.Server/Courses/CourseProbeController.cs +++ /dev/null @@ -1,62 +0,0 @@ -using Ahk.Web.Data; -using Ahk.Web.Data.Entities; -using Ahk.Web.Server.CourseContext; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; - -namespace Ahk.Web.Server.Courses; - -/// -/// Course context (/api/{course}/...). Temporary endpoint that proves course-scoping end-to-end: -/// the CourseMember policy gates access, and reads/writes are automatically confined to the current -/// course by the EF query filter. Removed once real course endpoints land in the port. -/// -[ApiController] -[Route("api/{course}/probe")] -[Authorize(Policy = CourseMembershipRequirement.PolicyName)] -public sealed class CourseProbeController : ControllerBase -{ - private readonly ApplicationDbContext db; - - public CourseProbeController(ApplicationDbContext db) => this.db = db; - - /// Returns notes for the current course only (enforced by the global query filter). - [HttpGet("notes")] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - public async Task>> GetNotes() - { - var notes = await db.CourseNotes - .AsNoTracking() - .OrderByDescending(n => n.CreatedAt) - .Select(n => new CourseNoteDto { Id = n.Id, Text = n.Text, CreatedAt = n.CreatedAt }) - .ToListAsync(); - - return Ok(notes); - } - - [HttpPost("notes")] - [ProducesResponseType(typeof(CourseNoteDto), StatusCodes.Status200OK)] - public async Task> AddNote([FromBody] CreateCourseNoteRequest request, [FromServices] ICurrentCourseProvider currentCourse) - { - var note = new CourseNote { CourseId = currentCourse.CurrentCourseId!.Value, Text = request.Text }; - db.CourseNotes.Add(note); - await db.SaveChangesAsync(); - - return Ok(new CourseNoteDto { Id = note.Id, Text = note.Text, CreatedAt = note.CreatedAt }); - } -} - -public sealed class CourseNoteDto -{ - public Guid Id { get; set; } - - public string Text { get; set; } = string.Empty; - - public DateTimeOffset CreatedAt { get; set; } -} - -public sealed class CreateCourseNoteRequest -{ - public string Text { get; set; } = string.Empty; -} diff --git a/ahk-backend/Ahk.Web.Server/Courses/GradesController.cs b/ahk-backend/Ahk.Web.Server/Courses/GradesController.cs new file mode 100644 index 00000000..afa22ef1 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Courses/GradesController.cs @@ -0,0 +1,43 @@ +using Ahk.Web.Data.Entities; +using Ahk.Web.Server.CourseContext; +using Ahk.Web.Services.Grading; +using Ahk.Web.Services.Grading.Dto; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace Ahk.Web.Server.Courses; + +/// +/// Course-scoped final grades — the port of the legacy list-grades/{*repoprefix} function, with the +/// repository prefix replaced by the {course} route segment. The CSV endpoint preserves the original export +/// format so downstream administration keeps working. +/// +[ApiController] +[Route("api/{course}/grades")] +[Authorize(Policy = CourseMembershipRequirement.PolicyName)] +public sealed class GradesController : ControllerBase +{ + private readonly IGradeListingService gradeListing; + + public GradesController(IGradeListingService gradeListing) => this.gradeListing = gradeListing; + + [HttpGet] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + public async Task>> List(CancellationToken cancellationToken) + { + var course = CurrentCourse(); + return Ok(await gradeListing.ListAsync(course.Id, cancellationToken)); + } + + [HttpGet("csv")] + [Produces("text/csv")] + [ProducesResponseType(typeof(string), StatusCodes.Status200OK)] + public async Task ExportCsv(CancellationToken cancellationToken) + { + var course = CurrentCourse(); + var csv = await gradeListing.ExportCsvAsync(course.Id, cancellationToken); + return File(System.Text.Encoding.UTF8.GetBytes(csv), "text/csv", $"{course.Slug}-grades.csv"); + } + + private Course CurrentCourse() => (Course)HttpContext.Items[CourseResolutionMiddleware.CourseItemKey]!; +} diff --git a/ahk-backend/Ahk.Web.Server/Courses/SubmissionStatusesController.cs b/ahk-backend/Ahk.Web.Server/Courses/SubmissionStatusesController.cs new file mode 100644 index 00000000..4cbdb8de --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Courses/SubmissionStatusesController.cs @@ -0,0 +1,30 @@ +using Ahk.Web.Data.Entities; +using Ahk.Web.Server.CourseContext; +using Ahk.Web.Services.StatusTracking; +using Ahk.Web.Services.StatusTracking.Dto; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace Ahk.Web.Server.Courses; + +/// +/// Course-scoped submission status list — the port of the legacy list-statuses/{*repoprefix} function, +/// with the repository prefix replaced by the {course} route segment. +/// +[ApiController] +[Route("api/{course}/statuses")] +[Authorize(Policy = CourseMembershipRequirement.PolicyName)] +public sealed class SubmissionStatusesController : ControllerBase +{ + private readonly IStatusTrackingService statusTracking; + + public SubmissionStatusesController(IStatusTrackingService statusTracking) => this.statusTracking = statusTracking; + + [HttpGet] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + public async Task>> List(CancellationToken cancellationToken) + { + var course = (Course)HttpContext.Items[CourseResolutionMiddleware.CourseItemKey]!; + return Ok(await statusTracking.ListStatusesAsync(course.Id, cancellationToken)); + } +} diff --git a/ahk-backend/Ahk.Web.Server/MockOidc/MockOidcEndpoints.cs b/ahk-backend/Ahk.Web.Server/MockOidc/MockOidcEndpoints.cs new file mode 100644 index 00000000..59a9f5e5 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/MockOidc/MockOidcEndpoints.cs @@ -0,0 +1,183 @@ +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using Ahk.Web.Server.Configuration; +using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Tokens; + +namespace Ahk.Web.Server.MockOidc; + +/// +/// Minimal in-app OpenID Provider for development only. Exists because just the production redirect URI +/// (https://ahk.aut.bme.hu/signin-oidc) is registered with the BME IdP, so the real provider cannot be used +/// from localhost. +/// +/// It mirrors the shape of BME's discovery document (query response mode, client_secret_post, the same claim +/// names including neptun_code) and issues genuinely signed RS256 id_tokens, so the ASP.NET OIDC handler runs +/// its real validation path against it. +/// +public static class MockOidcEndpoints +{ + public const string BasePath = "/mock-oidc"; + + /// Holds the developer's chosen persona between /persona and the next /authorize. + private const string PersonaCookie = "ahk_mock_oidc_persona"; + + public static IEndpointRouteBuilder MapMockOidcProvider(this IEndpointRouteBuilder endpoints) + { + var group = endpoints.MapGroup(BasePath).AllowAnonymous(); + + group.MapGet("/.well-known/openid-configuration", (IOptions options) => + { + var issuer = Issuer(options.Value); + return Results.Json(new + { + issuer, + authorization_endpoint = $"{issuer}/authorize", + token_endpoint = $"{issuer}/token", + userinfo_endpoint = $"{issuer}/userinfo", + jwks_uri = $"{issuer}/keyset", + response_types_supported = new[] { "code" }, + subject_types_supported = new[] { "public" }, + grant_types_supported = new[] { "authorization_code" }, + id_token_signing_alg_values_supported = new[] { "RS256" }, + token_endpoint_auth_methods_supported = new[] { "client_secret_post", "client_secret_basic" }, + scopes_supported = new[] { "openid", "profile", "email", "userinfo", "offline_access" }, + response_modes_supported = new[] { "query", "fragment", "form_post" }, + claims_supported = new[] + { + "aud", "iss", "sub", "iat", "exp", "auth_time", "email", "name", + "family_name", "given_name", "eduperson_scoped_affiliation", "neptun_code", + }, + }); + }); + + // Persona selection. The OIDC handler builds the authorize URL itself, so a custom parameter cannot be + // threaded through the challenge — the choice is parked in a cookie instead. + // Usage: navigate to /mock-oidc/persona?user=student, then sign in as usual. + group.MapGet("/persona", (HttpContext context, string? user) => + { + var selected = MockOidcUsers.Resolve(user); + context.Response.Cookies.Append(PersonaCookie, selected.Key, new CookieOptions + { + HttpOnly = true, + Secure = true, + SameSite = SameSiteMode.Lax, + Path = "/", + }); + + return Results.Json(new { persona = selected.Key, available = MockOidcUsers.All.Keys }); + }); + + // No login UI: pick the persona (query, else cookie, else default) and redirect straight back with a code. + group.MapGet("/authorize", (HttpContext context, MockOidcCodeStore codes, IOptions options) => + { + var query = context.Request.Query; + var redirectUri = query["redirect_uri"].ToString(); + var clientId = query["client_id"].ToString(); + + if (string.IsNullOrEmpty(redirectUri)) + return Results.BadRequest(new { error = "invalid_request", error_description = "redirect_uri is required" }); + + if (!string.Equals(clientId, options.Value.ClientId, StringComparison.Ordinal)) + return Results.BadRequest(new { error = "unauthorized_client", error_description = $"unexpected client_id '{clientId}'" }); + + var personaKey = query["mock_user"].ToString() is { Length: > 0 } q + ? q + : context.Request.Cookies[PersonaCookie]; + var user = MockOidcUsers.Resolve(personaKey); + var code = codes.Issue(user, query["nonce"].ToString() is { Length: > 0 } n ? n : null, clientId); + + var separator = redirectUri.Contains('?', StringComparison.Ordinal) ? "&" : "?"; + var location = $"{redirectUri}{separator}code={Uri.EscapeDataString(code)}"; + + var state = query["state"].ToString(); + if (!string.IsNullOrEmpty(state)) + location += $"&state={Uri.EscapeDataString(state)}"; + + return Results.Redirect(location); + }); + + group.MapPost("/token", async (HttpContext context, MockOidcCodeStore codes, MockOidcSigningKey signingKey, IOptions options) => + { + var form = await context.Request.ReadFormAsync(); + var redeemed = codes.Redeem(form["code"].ToString()); + if (redeemed is null) + return Results.BadRequest(new { error = "invalid_grant", error_description = "unknown or already-used code" }); + + // client_secret_post: the handler sends credentials in the body. + if (!string.Equals(form["client_secret"].ToString(), options.Value.ClientSecret, StringComparison.Ordinal)) + return Results.BadRequest(new { error = "invalid_client", error_description = "client_secret mismatch" }); + + var issuer = Issuer(options.Value); + var now = DateTimeOffset.UtcNow; + + var claims = new List + { + new(JwtRegisteredClaimNames.Sub, redeemed.User.Subject), + new(JwtRegisteredClaimNames.Iat, now.ToUnixTimeSeconds().ToString(System.Globalization.CultureInfo.InvariantCulture), ClaimValueTypes.Integer64), + new("auth_time", now.ToUnixTimeSeconds().ToString(System.Globalization.CultureInfo.InvariantCulture), ClaimValueTypes.Integer64), + }; + + if (redeemed.Nonce is not null) + claims.Add(new Claim(JwtRegisteredClaimNames.Nonce, redeemed.Nonce)); + + var token = new JwtSecurityToken( + issuer: issuer, + audience: redeemed.ClientId, + claims: claims, + notBefore: now.UtcDateTime, + expires: now.AddMinutes(10).UtcDateTime, + signingCredentials: signingKey.SigningCredentials); + + var idToken = new JwtSecurityTokenHandler().WriteToken(token); + + // The access token is opaque here; the userinfo endpoint resolves it through the code store's persona. + return Results.Json(new + { + access_token = $"mock-access-{redeemed.User.Key}", + token_type = "Bearer", + expires_in = 600, + id_token = idToken, + }); + }); + + group.MapGet("/userinfo", (HttpContext context) => + { + var authorization = context.Request.Headers.Authorization.ToString(); + const string prefix = "Bearer mock-access-"; + if (!authorization.StartsWith(prefix, StringComparison.Ordinal)) + return Results.Unauthorized(); + + var user = MockOidcUsers.Resolve(authorization[prefix.Length..]); + + // Claim names deliberately match BME's claims_supported. + var payload = new Dictionary(StringComparer.Ordinal) + { + ["sub"] = user.Subject, + ["email"] = user.Email, + ["name"] = user.Name, + ["given_name"] = user.GivenName, + ["family_name"] = user.FamilyName, + }; + + if (user.NeptunCode is not null) + payload["neptun_code"] = user.NeptunCode; + + if (user.Affiliations.Length > 0) + payload["eduperson_scoped_affiliation"] = user.Affiliations; // multi-valued, as at BME + + return Results.Json(payload); + }); + + group.MapGet("/keyset", (MockOidcSigningKey signingKey) + => Results.Json(new { keys = new[] { signingKey.ToJsonWebKey() } })); + + return endpoints; + } + + /// + /// The mock's issuer is the configured Authority, so the handler's issuer validation matches without any + /// special-casing (dev config points Authority at this app's own /mock-oidc). + /// + private static string Issuer(OidcOptions options) => options.Authority!.TrimEnd('/'); +} diff --git a/ahk-backend/Ahk.Web.Server/MockOidc/MockOidcSigningKey.cs b/ahk-backend/Ahk.Web.Server/MockOidc/MockOidcSigningKey.cs new file mode 100644 index 00000000..2aa7624b --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/MockOidc/MockOidcSigningKey.cs @@ -0,0 +1,46 @@ +using System.Security.Cryptography; +using Microsoft.IdentityModel.Tokens; + +namespace Ahk.Web.Server.MockOidc; + +/// +/// In-memory RSA key used by the development mock provider to sign id_tokens, and published through its JWKS. +/// Generated once per process — restarting the app rotates it, which is fine for a dev-only provider. +/// +/// The mock signs tokens for real (rather than stubbing validation out) so the ASP.NET OIDC handler runs its +/// genuine signature/issuer/audience/nonce checks; otherwise the mock would prove nothing about the real flow. +/// +public sealed class MockOidcSigningKey : IDisposable +{ + public const string KeyId = "ahk-mock-key"; + + private readonly RSA rsa; + + public MockOidcSigningKey() + { + rsa = RSA.Create(2048); + SecurityKey = new RsaSecurityKey(rsa) { KeyId = KeyId }; + SigningCredentials = new SigningCredentials(SecurityKey, SecurityAlgorithms.RsaSha256); + } + + public RsaSecurityKey SecurityKey { get; } + + public SigningCredentials SigningCredentials { get; } + + /// Public key as a JWKS entry (RFC 7517), which is what the handler fetches from the keyset endpoint. + public object ToJsonWebKey() + { + var parameters = rsa.ExportParameters(includePrivateParameters: false); + return new + { + kty = "RSA", + use = "sig", + alg = "RS256", + kid = KeyId, + n = Base64UrlEncoder.Encode(parameters.Modulus), + e = Base64UrlEncoder.Encode(parameters.Exponent), + }; + } + + public void Dispose() => rsa.Dispose(); +} diff --git a/ahk-backend/Ahk.Web.Server/MockOidc/MockOidcUsers.cs b/ahk-backend/Ahk.Web.Server/MockOidc/MockOidcUsers.cs new file mode 100644 index 00000000..b209258f --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/MockOidc/MockOidcUsers.cs @@ -0,0 +1,79 @@ +using System.Collections.Concurrent; + +namespace Ahk.Web.Server.MockOidc; + +/// A fixed persona the mock provider can authenticate as, mirroring BME's claim set. +public sealed record MockOidcUser( + string Key, + string Subject, + string Email, + string Name, + string GivenName, + string FamilyName, + string? NeptunCode, + string[] Affiliations); + +/// +/// Fixed development personas. The default is an instructor; ?mock_user=student (or =noclaims) +/// selects another so claim handling — multi-valued affiliation, missing neptun code — can be exercised. +/// +public static class MockOidcUsers +{ + public const string DefaultKey = "instructor"; + + public static readonly IReadOnlyDictionary All = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + [DefaultKey] = new( + Key: DefaultKey, + Subject: "mock-sub-instructor", + Email: "teacher@bme.hu", + Name: "Teszt Tanár", + GivenName: "Teszt", + FamilyName: "Tanár", + NeptunCode: "TEACH1", + Affiliations: new[] { "staff@bme.hu", "employee@bme.hu" }), + + ["student"] = new( + Key: "student", + Subject: "mock-sub-student", + Email: "student@bme.hu", + Name: "Teszt Hallgató", + GivenName: "Teszt", + FamilyName: "Hallgató", + NeptunCode: "ABC123", + Affiliations: new[] { "student@bme.hu" }), + + // Directory account with no neptun code and no affiliation — the sparse-claims case. + ["noclaims"] = new( + Key: "noclaims", + Subject: "mock-sub-noclaims", + Email: "sparse@bme.hu", + Name: "Sparse User", + GivenName: "Sparse", + FamilyName: "User", + NeptunCode: null, + Affiliations: Array.Empty()), + }; + + public static MockOidcUser Resolve(string? key) + => key is not null && All.TryGetValue(key, out var user) ? user : All[DefaultKey]; +} + +/// Authorization codes issued by the mock, held in memory until redeemed at the token endpoint. +public sealed class MockOidcCodeStore +{ + private readonly ConcurrentDictionary codes = new(StringComparer.Ordinal); + + public string Issue(MockOidcUser user, string? nonce, string clientId) + { + var code = Guid.NewGuid().ToString("N"); + codes[code] = new MockOidcAuthorizationCode(user, nonce, clientId); + return code; + } + + /// Single-use, like a real authorization code. + public MockOidcAuthorizationCode? Redeem(string? code) + => code is not null && codes.TryRemove(code, out var value) ? value : null; +} + +public sealed record MockOidcAuthorizationCode(MockOidcUser User, string? Nonce, string ClientId); diff --git a/ahk-backend/Ahk.Web.Server/Program.cs b/ahk-backend/Ahk.Web.Server/Program.cs index 77a484e3..7faf9860 100644 --- a/ahk-backend/Ahk.Web.Server/Program.cs +++ b/ahk-backend/Ahk.Web.Server/Program.cs @@ -4,113 +4,255 @@ using Ahk.Web.Server.Auth; using Ahk.Web.Server.Configuration; using Ahk.Web.Server.CourseContext; +using Ahk.Web.Server.MockOidc; +using Ahk.Web.Services; +using System.Security.Claims; +using System.Text.Json; +using System.Text.Json.Serialization; +using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; -var builder = WebApplication.CreateBuilder(args); +namespace Ahk.Web.Server; -// ---- Options ---- -builder.Services.Configure(builder.Configuration.GetSection(OidcOptions.SectionName)); -var oidc = builder.Configuration.GetSection(OidcOptions.SectionName).Get() ?? new OidcOptions(); +public class Program +{ + /// + /// Session cookie name. Deliberately app-specific: cookies are scoped by host and ignore the port, so the + /// framework default would be shared with every other ASP.NET Identity app running on localhost. + /// + public const string ApplicationCookieName = "ahk.auth"; -// ---- EF Core + course scoping ---- -builder.Services.AddHttpContextAccessor(); -builder.Services.AddScoped(); -builder.Services.AddScoped(sp => sp.GetRequiredService()); -builder.Services.AddDbContext(options => - options.UseSqlServer(builder.Configuration.GetConnectionString("Default"))); + /// Cookie holding the external identity between the OIDC callback and sign-in. + public const string ExternalCookieName = "ahk.auth.external"; -// ---- Identity (cookie-based; no MapIdentityApi — see plan) ---- -builder.Services - .AddIdentity(options => - { - options.User.RequireUniqueEmail = false; - options.SignIn.RequireConfirmedAccount = false; - options.Password.RequireNonAlphanumeric = false; - }) - .AddEntityFrameworkStores() - .AddDefaultTokenProviders(); - -// The SPA calls the API; make the cookie handler return 401/403 instead of redirecting to login/denied pages. -builder.Services.ConfigureApplicationCookie(options => -{ - options.Cookie.HttpOnly = true; - options.Cookie.SameSite = SameSiteMode.Lax; - options.Cookie.SecurePolicy = CookieSecurePolicy.Always; - options.Events.OnRedirectToLogin = ctx => + public static async Task Main(string[] args) { - ctx.Response.StatusCode = StatusCodes.Status401Unauthorized; - return Task.CompletedTask; - }; - options.Events.OnRedirectToAccessDenied = ctx => - { - ctx.Response.StatusCode = StatusCodes.Status403Forbidden; - return Task.CompletedTask; - }; -}); + var builder = WebApplication.CreateBuilder(args); + ConfigureServices(builder); -// ---- Generic OIDC external login (registered only when configured) ---- -if (oidc.IsEnabled) -{ - builder.Services.AddAuthentication().AddOpenIdConnect(ExternalAuthController.Scheme, options => + var app = builder.Build(); + await ConfigurePipelineAsync(app); + + await app.RunAsync(); + } + + private static void ConfigureServices(WebApplicationBuilder builder) { - options.Authority = oidc.Authority; - options.ClientId = oidc.ClientId; - options.ClientSecret = oidc.ClientSecret; - options.ResponseType = "code"; - options.UsePkce = true; - options.SaveTokens = true; - options.CallbackPath = "/signin-oidc"; - options.SignInScheme = IdentityConstants.ExternalScheme; - options.Scope.Clear(); - options.Scope.Add("openid"); - options.Scope.Add("profile"); - foreach (var scope in oidc.Scopes) - options.Scope.Add(scope); - options.GetClaimsFromUserInfoEndpoint = true; - }); -} + // ---- Options ---- + builder.Services.Configure(builder.Configuration.GetSection(OidcOptions.SectionName)); + var oidc = builder.Configuration.GetSection(OidcOptions.SectionName).Get() ?? new OidcOptions(); -// ---- Authorization ---- -builder.Services.AddScoped(); -builder.Services.AddAuthorization(options => -{ - options.AddPolicy(CourseMembershipRequirement.PolicyName, policy => - policy.Requirements.Add(new CourseMembershipRequirement())); -}); + // ---- EF Core + course scoping ---- + builder.Services.AddHttpContextAccessor(); + builder.Services.AddScoped(); + builder.Services.AddScoped(sp => sp.GetRequiredService()); + builder.Services.AddDbContext(options => + options.UseSqlServer(builder.Configuration.GetConnectionString("Default"))); -// ---- MVC + OpenAPI (NSwag document consumed by the Angular code generator) ---- -builder.Services.AddControllers(); -builder.Services.AddOpenApiDocument(settings => -{ - settings.DocumentName = "v1"; - settings.Title = "AHK API"; - settings.Version = "v1"; -}); + // ---- Identity (cookie-based; no MapIdentityApi — see plan) ---- + builder.Services + .AddIdentity(options => + { + options.User.RequireUniqueEmail = false; + options.SignIn.RequireConfirmedAccount = false; + options.Password.RequireNonAlphanumeric = false; + }) + .AddEntityFrameworkStores() + .AddDefaultTokenProviders(); -var app = builder.Build(); + // The SPA calls the API; make the cookie handler return 401/403 instead of redirecting to login/denied pages. + builder.Services.ConfigureApplicationCookie(options => + { + // Named, not left at ASP.NET's default ".AspNetCore.Identity.Application". Browsers scope cookies + // by host and ignore the port, so on localhost every ASP.NET Identity app shares that default name + // — another project's cookie lands on this one, and because this app uses int keys, its GUID user + // id blows up SecurityStampValidator with "not a valid value for Int32". + options.Cookie.Name = ApplicationCookieName; + options.Cookie.HttpOnly = true; + options.Cookie.SameSite = SameSiteMode.Lax; + options.Cookie.SecurePolicy = CookieSecurePolicy.Always; + options.Events.OnRedirectToLogin = ctx => + { + ctx.Response.StatusCode = StatusCodes.Status401Unauthorized; + return Task.CompletedTask; + }; + options.Events.OnRedirectToAccessDenied = ctx => + { + ctx.Response.StatusCode = StatusCodes.Status403Forbidden; + return Task.CompletedTask; + }; -if (app.Environment.IsDevelopment()) -{ - app.UseOpenApi(); // /swagger/v1/swagger.json - app.UseSwaggerUi(); // /swagger - await DevDataSeeder.SeedAsync(app.Services); -} + // Belt and braces: a cookie this app cannot make sense of must sign the caller out, not throw. + // AddIdentity points OnValidatePrincipal at the security-stamp validator, so it is called here + // rather than replaced. + options.Events.OnValidatePrincipal = async context => + { + try + { + await SecurityStampValidator.ValidatePrincipalAsync(context); + } + catch (Exception ex) when (ex is ArgumentException or FormatException) + { + context.RejectPrincipal(); + await context.HttpContext.SignOutAsync(IdentityConstants.ApplicationScheme); + } + }; + }); -app.UseHttpsRedirection(); + // Same collision, shorter-lived cookie: this one carries the external identity between the OIDC + // callback and sign-in. + builder.Services.ConfigureExternalCookie(options => + { + options.Cookie.Name = ExternalCookieName; + options.Cookie.HttpOnly = true; + options.Cookie.SecurePolicy = CookieSecurePolicy.Always; + }); -app.UseRouting(); -app.UseAuthentication(); -app.UseMiddleware(); -app.UseAuthorization(); + // ---- Generic OIDC external login (registered only when configured) ---- + if (oidc.IsEnabled) + { + builder.Services.AddAuthentication().AddOpenIdConnect(ExternalAuthController.Scheme, options => + { + options.Authority = oidc.Authority; + options.ClientId = oidc.ClientId; + options.ClientSecret = oidc.ClientSecret; -app.MapControllers(); + options.ResponseType = "code"; -app.Run(); + // query, not the ASP.NET default of form_post: form_post makes the callback a cross-site POST, + // so the correlation cookie is dropped under SameSite=Lax and login fails with "Correlation failed". + options.ResponseMode = oidc.ResponseMode; -// Exposed for WebApplicationFactory-based integration tests. -public partial class Program -{ + // Off for BME: the IdP does not advertise code_challenge_methods_supported, and we authenticate + // with client_secret_post, so PKCE is defence-in-depth rather than required. + options.UsePkce = oidc.UsePkce; + + options.SaveTokens = oidc.SaveTokens; + options.CallbackPath = "/signin-oidc"; + options.SignedOutCallbackPath = "/signout-callback-oidc"; + options.SignInScheme = IdentityConstants.ExternalScheme; + options.GetClaimsFromUserInfoEndpoint = true; + + // Exactly the registered scopes — requesting an unregistered one (e.g. profile) gets rejected. + options.Scope.Clear(); + foreach (var scope in oidc.Scopes) + options.Scope.Add(scope); + + // OpenIdConnectOptions ships only DeleteClaim actions — it maps NO standard claims. Anything + // arriving from the userinfo endpoint (rather than inside the id_token) is therefore dropped + // unless mapped explicitly. BME returns these via userinfo, so they must be listed here. + options.ClaimActions.MapUniqueJsonKey(ClaimTypes.Email, "email"); + options.ClaimActions.MapUniqueJsonKey(ClaimTypes.Name, "name"); + options.ClaimActions.MapUniqueJsonKey(ClaimTypes.GivenName, "given_name"); + options.ClaimActions.MapUniqueJsonKey(ClaimTypes.Surname, "family_name"); + + // BME-specific claims. neptun_code is single-valued; eduperson_scoped_affiliation is an array, + // so it needs a custom action that joins the values. Note the resolver receives the whole + // userinfo payload, not just the claim, so the property is looked up explicitly. + options.ClaimActions.MapUniqueJsonKey(BmeClaimTypes.NeptunCode, BmeClaimTypes.NeptunCode); + options.ClaimActions.MapCustomJson(BmeClaimTypes.Affiliation, root => + { + if (!root.TryGetProperty(BmeClaimTypes.Affiliation, out var value)) + return null; + + return value.ValueKind == JsonValueKind.Array + ? string.Join(';', value.EnumerateArray().Select(v => v.ToString())) + : value.ToString(); + }); + + options.Events.OnRedirectToIdentityProvider = context => + { + // The dev proxy rewrites Host, so the computed redirect_uri would point at the backend port + // instead of the browser's origin. In production this is left unset and computed normally. + if (!string.IsNullOrWhiteSpace(oidc.RedirectUri)) + context.ProtocolMessage.RedirectUri = oidc.RedirectUri; + + return Task.CompletedTask; + }; + + if (oidc.UseMockProvider) + { + // The app fetches discovery/token/jwks from its own HTTPS endpoint, whose dev certificate is + // self-signed. Development only. + options.BackchannelHttpHandler = new HttpClientHandler + { + ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator, + }; + } + }); + } + + // ---- Authorization ---- + builder.Services.AddScoped(); + builder.Services.AddAuthorization(options => + { + options.AddPolicy(CourseMembershipRequirement.PolicyName, policy => + policy.Requirements.Add(new CourseMembershipRequirement())); + }); + + // ---- Development-only mock OpenID provider ---- + if (oidc.UseMockProvider) + { + builder.Services.AddSingleton(); + builder.Services.AddSingleton(); + } + + // Behind the production reverse proxy (TLS terminated upstream) the original scheme/host must be + // honoured, otherwise the generated redirect_uri would be http://internal instead of https://ahk.aut.bme.hu. + builder.Services.Configure(options => + { + options.ForwardedHeaders = ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost | ForwardedHeaders.XForwardedFor; + options.KnownNetworks.Clear(); + options.KnownProxies.Clear(); + }); + + // ---- Domain services (Ahk.Web.Services) ---- + builder.Services.AddMemoryCache(); + builder.Services.AddAhkServices(); + + // ---- MVC + OpenAPI (NSwag document consumed by the Angular code generator) ---- + // Enums travel as names, not ordinals: the generated TypeScript client then models them as string + // literal unions ('Instructor' | 'Admin'), which survives reordering an enum member. + builder.Services.AddControllers().AddJsonOptions(options => + options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter())); + builder.Services.AddOpenApiDocument(settings => + { + settings.DocumentName = "v1"; + settings.Title = "AHK API"; + settings.Version = "v1"; + }); + } + + private static async Task ConfigurePipelineAsync(WebApplication app) + { + // Must run before anything that builds absolute URLs (the OIDC redirect_uri in particular). + app.UseForwardedHeaders(); + + var oidc = app.Services.GetRequiredService>().Value; + + if (app.Environment.IsDevelopment()) + { + app.UseOpenApi(); // /swagger/v1/swagger.json + app.UseSwaggerUi(); // /swagger + await DevDataSeeder.SeedAsync(app.Services); + } + + app.UseHttpsRedirection(); + + app.UseRouting(); + app.UseAuthentication(); + app.UseMiddleware(); + app.UseAuthorization(); + + // Development-only stand-in for the BME IdP; never mapped outside Development. + if (app.Environment.IsDevelopment() && oidc.UseMockProvider) + app.MapMockOidcProvider(); + + app.MapControllers(); + } } diff --git a/ahk-backend/Ahk.Web.Server/appsettings.Development.json b/ahk-backend/Ahk.Web.Server/appsettings.Development.json index da03147c..9051f3da 100644 --- a/ahk-backend/Ahk.Web.Server/appsettings.Development.json +++ b/ahk-backend/Ahk.Web.Server/appsettings.Development.json @@ -10,10 +10,14 @@ }, "Authentication": { "Oidc": { - "Authority": "", - "ClientId": "", - "ClientSecret": "", - "Scopes": [ "email" ] + "_comment": "Development uses the in-app mock provider (MockOidc/) because only the production redirect URI is registered with the BME IdP.", + "UseMockProvider": true, + "Authority": "https://localhost:7443/mock-oidc", + "ClientId": "AUTAhkClientDev", + "ClientSecret": "dev-mock-secret", + "Scopes": [ "openid", "email", "userinfo" ], + "RedirectUri": "https://localhost:4200/signin-oidc", + "PostLogoutRedirectUri": "https://localhost:4200/signout-callback-oidc" } } } diff --git a/ahk-backend/Ahk.Web.Server/appsettings.json b/ahk-backend/Ahk.Web.Server/appsettings.json index 7fa5cc40..6871f296 100644 --- a/ahk-backend/Ahk.Web.Server/appsettings.json +++ b/ahk-backend/Ahk.Web.Server/appsettings.json @@ -11,10 +11,14 @@ }, "Authentication": { "Oidc": { - "Authority": "", - "ClientId": "", + "_comment": "BME IdP (Shibboleth). ClientSecret is NEVER stored here — supply it via the Authentication__Oidc__ClientSecret environment variable (or user-secrets locally).", + "Authority": "https://idp.bme.hu", + "ClientId": "AUTAhkClient", "ClientSecret": "", - "Scopes": [ "email" ] + "Scopes": [ "openid", "email", "userinfo" ], + "UsePkce": false, + "ResponseMode": "query", + "EndSessionEndpoint": "" } } } diff --git a/ahk-backend/Ahk.Web.Services/Ahk.Web.Services.csproj b/ahk-backend/Ahk.Web.Services/Ahk.Web.Services.csproj new file mode 100644 index 00000000..2974869a --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/Ahk.Web.Services.csproj @@ -0,0 +1,25 @@ + + + + + + + + + <_Parameter1>Ahk.Web.Server.Tests + + + + + + + + + + + net10.0 + enable + enable + + + diff --git a/ahk-backend/Ahk.Web.Services/Courses/CourseResolutionService.cs b/ahk-backend/Ahk.Web.Services/Courses/CourseResolutionService.cs new file mode 100644 index 00000000..f499aaa9 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/Courses/CourseResolutionService.cs @@ -0,0 +1,70 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Microsoft.EntityFrameworkCore; + +namespace Ahk.Web.Services.Courses; + +public interface ICourseResolutionService +{ + Task ResolveBySlugAsync(string slug, CancellationToken cancellationToken = default); + + Task ResolveByRepositoryAsync(string gitHubRepoName, CancellationToken cancellationToken = default); + + Task ResolveByWebhookTokenAsync(string token, CancellationToken cancellationToken = default); +} + +/// +/// Maps an incoming request to a course. Browser requests use the {course} route slug; machine-to-machine +/// requests have no such segment, so they resolve from the payload's repository (organization + repo-name +/// prefix) or from the CI callback token. +/// +/// The repo-name prefix rule is the explicit form of the original system's implicit convention, where a course +/// *was* a repository-name prefix (ListConfirmedWithRepositoryPrefix / ListEventsForRepositories). +/// +public sealed class CourseResolutionService : ICourseResolutionService +{ + private readonly ApplicationDbContext db; + + public CourseResolutionService(ApplicationDbContext db) => this.db = db; + + public Task ResolveBySlugAsync(string slug, CancellationToken cancellationToken = default) + => db.Courses.AsNoTracking().FirstOrDefaultAsync(c => c.Slug == slug, cancellationToken); + + public async Task ResolveByRepositoryAsync(string gitHubRepoName, CancellationToken cancellationToken = default) + { + var repo = Normalize.RepoName(gitHubRepoName); + if (string.IsNullOrEmpty(repo)) + return null; + + // "owner/name" — the owner is the GitHub organization. + var slashIndex = repo.IndexOf('/', StringComparison.Ordinal); + var org = slashIndex > 0 ? repo[..slashIndex] : null; + var nameOnly = slashIndex > 0 ? repo[(slashIndex + 1)..] : repo; + + var candidates = await db.Courses.AsNoTracking() + .Where(c => c.GitHubOrganization != null && c.GitHubOrganization == org) + .ToListAsync(cancellationToken); + + if (candidates.Count == 0) + return null; + + if (candidates.Count == 1) + return candidates[0]; + + // Several courses share the organization: disambiguate on the repo-name prefix, longest match wins. + return candidates + .Where(c => !string.IsNullOrEmpty(c.RepoNamePrefix) && nameOnly.StartsWith(c.RepoNamePrefix!, StringComparison.Ordinal)) + .OrderByDescending(c => c.RepoNamePrefix!.Length) + .FirstOrDefault(); + } + + public async Task ResolveByWebhookTokenAsync(string token, CancellationToken cancellationToken = default) + { + var match = await db.CourseWebhookTokens + .IgnoreQueryFilters() + .AsNoTracking() + .FirstOrDefaultAsync(t => t.Token == token && t.RevokedAt == null, cancellationToken); + + return match is null ? null : await db.Courses.AsNoTracking().FirstOrDefaultAsync(c => c.Id == match.CourseId, cancellationToken); + } +} diff --git a/ahk-backend/Ahk.Web.Services/Courses/WebhookTokenService.cs b/ahk-backend/Ahk.Web.Services/Courses/WebhookTokenService.cs new file mode 100644 index 00000000..14f9227b --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/Courses/WebhookTokenService.cs @@ -0,0 +1,116 @@ +using System.Security.Cryptography; +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Memory; + +namespace Ahk.Web.Services.Courses; + +public interface IWebhookTokenService +{ + Task GetSecretForTokenAsync(string token, CancellationToken cancellationToken = default); + + /// Lists a course's tokens, newest first. Secrets are not returned — they are shown once, at creation. + Task> ListForCourseAsync(int courseId, CancellationToken cancellationToken = default); + + /// + /// Issues a new token/secret pair for a course. The returned entity carries the plaintext secret; it is the + /// only time the caller can show it, so the admin UI surfaces it immediately. + /// + Task CreateAsync(int courseId, string? description, CancellationToken cancellationToken = default); + + /// Revokes a token so callbacks signed with it are rejected. Returns false when it does not exist. + Task RevokeAsync(int courseId, int tokenId, CancellationToken cancellationToken = default); +} + +/// +/// Owns the CI callback tokens: the hot-path secret lookup used by the evaluation-result webhook and the +/// administrative issue/revoke operations. Port of +/// grade-management/.../TokenManagement/TokenManagementService.cs, including its one-hour memory cache — +/// this runs on every evaluation-result callback, so the cache matters. +/// +/// Issue and revoke live here rather than in the controller precisely because of that cache: a revoked token +/// would otherwise keep authenticating callbacks for up to an hour. +/// +public sealed class WebhookTokenService : IWebhookTokenService +{ + private static readonly TimeSpan CacheDuration = TimeSpan.FromHours(1); + + private readonly ApplicationDbContext db; + private readonly IMemoryCache cache; + + public WebhookTokenService(ApplicationDbContext db, IMemoryCache cache) + { + this.db = db; + this.cache = cache; + } + + public async Task GetSecretForTokenAsync(string token, CancellationToken cancellationToken = default) + { + var key = CacheKey(token); + if (cache.TryGetValue(key, out var cached)) + return cached; + + var secret = await db.CourseWebhookTokens + .IgnoreQueryFilters() + .AsNoTracking() + .Where(t => t.Token == token && t.RevokedAt == null) + .Select(t => t.Secret) + .FirstOrDefaultAsync(cancellationToken); + + cache.Set(key, secret, CacheDuration); + return secret; + } + + public async Task> ListForCourseAsync(int courseId, CancellationToken cancellationToken = default) => + await db.CourseWebhookTokens + .IgnoreQueryFilters() + .AsNoTracking() + .Where(t => t.CourseId == courseId) + .OrderByDescending(t => t.CreatedAt) + .ToListAsync(cancellationToken); + + public async Task CreateAsync(int courseId, string? description, CancellationToken cancellationToken = default) + { + var entity = new CourseWebhookToken + { + CourseId = courseId, + Token = GenerateSecret(24), + Secret = GenerateSecret(32), + Description = description, + }; + + db.CourseWebhookTokens.Add(entity); + await db.SaveChangesAsync(cancellationToken); + return entity; + } + + public async Task RevokeAsync(int courseId, int tokenId, CancellationToken cancellationToken = default) + { + var entity = await db.CourseWebhookTokens + .IgnoreQueryFilters() + .FirstOrDefaultAsync(t => t.Id == tokenId && t.CourseId == courseId, cancellationToken); + + if (entity is null) + return false; + + if (entity.RevokedAt is null) + { + entity.RevokedAt = DateTimeOffset.UtcNow; + await db.SaveChangesAsync(cancellationToken); + } + + // Drop the cached secret, otherwise the revoked token keeps authenticating callbacks until it expires. + cache.Remove(CacheKey(entity.Token)); + return true; + } + + private static string CacheKey(string token) => $"secrettotoken{token}"; + + /// URL-safe random string — these travel in an HTTP header and a workflow secret. + private static string GenerateSecret(int byteLength) => + Convert.ToBase64String(RandomNumberGenerator.GetBytes(byteLength)) + .Replace('+', '-') + .Replace('/', '_') + .TrimEnd('='); +} diff --git a/ahk-backend/Ahk.Web.Services/Grading/CsvExporter.cs b/ahk-backend/Ahk.Web.Services/Grading/CsvExporter.cs new file mode 100644 index 00000000..ac8ace66 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/Grading/CsvExporter.cs @@ -0,0 +1,52 @@ +using System.Globalization; +using System.Text; +using Ahk.Web.Services.Grading.Dto; + +namespace Ahk.Web.Services.Grading; + +/// +/// Semicolon-separated grade export. Ported verbatim from +/// grade-management/.../ListGrades/CsvExporter.cs — the column layout (Neptun;GitHubRepo;GitHubPr then +/// one column per distinct exercise name, sorted) and the "0.##" invariant number format are relied on by +/// downstream administration, so they must not drift. +/// +public static class CsvExporter +{ + public static string GetCsv(IReadOnlyCollection results) + { + var exNames = results.SelectMany(r => r.Points.Keys) + .Distinct(StringComparer.OrdinalIgnoreCase) + .OrderBy(s => s, StringComparer.Ordinal) + .ToList(); + + var str = new StringBuilder(); + + var values = new List { "Neptun", "GitHubRepo", "GitHubPr" }; + values.AddRange(exNames); + str.AppendLine(FormatLine(values)); + + foreach (var r in results) + { + values.Clear(); + values.Add(r.Neptun.ToUpperInvariant()); + values.Add(r.Repo); + values.Add(r.PrUrl ?? string.Empty); + + foreach (var exName in exNames) + values.Add(r.Points.TryGetValue(exName, out var p) ? p.ToString("0.##", CultureInfo.InvariantCulture) : string.Empty); + + str.AppendLine(FormatLine(values)); + } + + return str.ToString(); + } + + private static string FormatLine(IReadOnlyCollection values) + { + if (values is null || values.Count == 0) + return string.Empty; + + var valuesString = values.Select(s => s is null ? string.Empty : s.Replace("\"", string.Empty, StringComparison.OrdinalIgnoreCase)); + return string.Join(";", valuesString); + } +} diff --git a/ahk-backend/Ahk.Web.Services/Grading/Dto/FinalStudentGrade.cs b/ahk-backend/Ahk.Web.Services/Grading/Dto/FinalStudentGrade.cs new file mode 100644 index 00000000..70f4f181 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/Grading/Dto/FinalStudentGrade.cs @@ -0,0 +1,17 @@ +namespace Ahk.Web.Services.Grading.Dto; + +/// +/// One student's final (latest confirmed) grade for a submission. Shape preserved from +/// grade-management/.../ListGrades/Dto/FinalStudentGrade.cs, including the exercise-name → points map +/// that drives the CSV column layout. +/// +public sealed class FinalStudentGrade +{ + public string Neptun { get; set; } = string.Empty; + + public string Repo { get; set; } = string.Empty; + + public string? PrUrl { get; set; } + + public IReadOnlyDictionary Points { get; set; } = new Dictionary(); +} diff --git a/ahk-backend/Ahk.Web.Services/Grading/Dto/GradeInputs.cs b/ahk-backend/Ahk.Web.Services/Grading/Dto/GradeInputs.cs new file mode 100644 index 00000000..1ac1531a --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/Grading/Dto/GradeInputs.cs @@ -0,0 +1,66 @@ +namespace Ahk.Web.Services.Grading.Dto; + +/// Teacher grade/override via the "/ahk ok 5 3.5 0" chatops command (was SetGradeEvent). +public sealed class SetGradeInput +{ + public string Neptun { get; set; } = string.Empty; + + public string Repository { get; set; } = string.Empty; + + public int PrNumber { get; set; } + + public string? PrUrl { get; set; } + + public string? Actor { get; set; } + + public string? Origin { get; set; } + + /// Positional point values; index maps to exercise order. + public IReadOnlyList Results { get; set; } = Array.Empty(); +} + +/// Teacher approval that keeps the automated points as-is (was ConfirmAutoGradeEvent). +public sealed class ConfirmAutoGradeInput +{ + public string Neptun { get; set; } = string.Empty; + + public string Repository { get; set; } = string.Empty; + + public int PrNumber { get; set; } + + public string? PrUrl { get; set; } + + public string? Actor { get; set; } + + public string? Origin { get; set; } +} + +/// Automated evaluation result posted by publish-results-pr (was AhkProcessResult). +public sealed class EvaluationResultInput +{ + public string NeptunCode { get; set; } = string.Empty; + + public string GitHubRepoName { get; set; } = string.Empty; + + public string? GitHubBranch { get; set; } + + public string? GitHubCommitHash { get; set; } + + public int? GitHubPullRequestNum { get; set; } + + public string? Origin { get; set; } + + public IReadOnlyList Result { get; set; } = Array.Empty(); +} + +/// One task line from result.txt (was AhkTaskResult). Points are summed per exercise before storage. +public sealed class EvaluationTaskResult +{ + public string? ExerciseName { get; set; } + + public string TaskName { get; set; } = string.Empty; + + public double Points { get; set; } + + public string? Comment { get; set; } +} diff --git a/ahk-backend/Ahk.Web.Services/Grading/GradeListingService.cs b/ahk-backend/Ahk.Web.Services/Grading/GradeListingService.cs new file mode 100644 index 00000000..efaf80ba --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/Grading/GradeListingService.cs @@ -0,0 +1,56 @@ +using Ahk.Web.Data; +using Ahk.Web.Services.Grading.Dto; +using Microsoft.EntityFrameworkCore; + +namespace Ahk.Web.Services.Grading; + +public interface IGradeListingService +{ + Task> ListAsync(int courseId, CancellationToken cancellationToken = default); + + Task ExportCsvAsync(int courseId, CancellationToken cancellationToken = default); +} + +/// +/// Final-grade listing and export. Port of grade-management/.../ListGrades/GradeListing.cs: take the +/// confirmed results, group by (neptun, submission), and keep the most recent one — the append-only history +/// means "current grade" is always the latest row. +/// +public sealed class GradeListingService : IGradeListingService +{ + private readonly ApplicationDbContext db; + + public GradeListingService(ApplicationDbContext db) => this.db = db; + + public async Task> ListAsync(int courseId, CancellationToken cancellationToken = default) + { + var confirmed = await db.GradeRecords + .IgnoreQueryFilters() + .AsNoTracking() + .Where(g => g.CourseId == courseId && g.Confirmed) + .Include(g => g.Points) + .Include(g => g.Submission) + .ToListAsync(cancellationToken); + + return confirmed + .GroupBy(g => new { g.Neptun, Repo = g.Submission!.GitHubRepoName }) + .Select(group => + { + var latest = group.OrderByDescending(g => g.Date).First(); + return new FinalStudentGrade + { + Neptun = group.Key.Neptun, + Repo = group.Key.Repo, + PrUrl = latest.PrUrl, + Points = latest.Points + .OrderBy(p => p.Order) + .GroupBy(p => p.Name) + .ToDictionary(p => p.Key, p => p.Last().Point), + }; + }) + .ToList(); + } + + public async Task ExportCsvAsync(int courseId, CancellationToken cancellationToken = default) + => CsvExporter.GetCsv(await ListAsync(courseId, cancellationToken)); +} diff --git a/ahk-backend/Ahk.Web.Services/Grading/GradeService.cs b/ahk-backend/Ahk.Web.Services/Grading/GradeService.cs new file mode 100644 index 00000000..d2ce7edf --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/Grading/GradeService.cs @@ -0,0 +1,152 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Ahk.Web.Services.Grading.Dto; +using Ahk.Web.Services.Submissions; +using Microsoft.EntityFrameworkCore; + +namespace Ahk.Web.Services.Grading; + +public interface IGradeService +{ + Task SetGradeAsync(int courseId, SetGradeInput input, CancellationToken cancellationToken = default); + + Task ConfirmAutoGradeAsync(int courseId, ConfirmAutoGradeInput input, CancellationToken cancellationToken = default); + + Task RecordEvaluationResultAsync(int courseId, EvaluationResultInput input, DateTimeOffset timestamp, CancellationToken cancellationToken = default); +} + +/// +/// Grade writes. Port of SetGradeService + ResultProcessor. Every operation **inserts** a new +/// — the history is append-only and the newest row is the current grade. +/// +/// Reachable from three entry points with three different course-resolution mechanisms (teacher endpoint via +/// route, chatops via webhook payload, CI callback via token), which is why is +/// always explicit rather than read from the ambient course context. +/// +public sealed class GradeService : IGradeService +{ + /// Actor recorded for results arriving from the automated evaluation callback. + public const string AutomatedActor = "grade-management-api"; + + private readonly ApplicationDbContext db; + private readonly ISubmissionResolver submissions; + + public GradeService(ApplicationDbContext db, ISubmissionResolver submissions) + { + this.db = db; + this.submissions = submissions; + } + + public async Task SetGradeAsync(int courseId, SetGradeInput input, CancellationToken cancellationToken = default) + { + var submission = await submissions.GetOrCreateAsync(courseId, input.Repository, input.Neptun, cancellationToken); + var previous = await GetLastResultAsync(courseId, submission.Id, input.PrNumber, cancellationToken); + + var points = BuildPoints(input.Results, previous?.Points); + return await AddResultAsync(courseId, submission, Normalize.Neptun(input.Neptun), input.PrNumber, input.PrUrl, + DateTimeOffset.UtcNow, input.Actor, input.Origin, confirmed: true, points, cancellationToken); + } + + public async Task ConfirmAutoGradeAsync(int courseId, ConfirmAutoGradeInput input, CancellationToken cancellationToken = default) + { + var submission = await submissions.GetOrCreateAsync(courseId, input.Repository, input.Neptun, cancellationToken); + var previous = await GetLastResultAsync(courseId, submission.Id, input.PrNumber, cancellationToken); + + // Confirmation keeps whatever the automated evaluation produced. + var points = previous?.Points + .OrderBy(p => p.Order) + .Select(p => (p.Name, p.Point)) + .ToList() ?? new List<(string, double)>(); + + return await AddResultAsync(courseId, submission, Normalize.Neptun(input.Neptun), input.PrNumber, input.PrUrl, + DateTimeOffset.UtcNow, input.Actor, input.Origin, confirmed: true, points, cancellationToken); + } + + public async Task RecordEvaluationResultAsync(int courseId, EvaluationResultInput input, DateTimeOffset timestamp, CancellationToken cancellationToken = default) + { + var submission = await submissions.GetOrCreateAsync(courseId, input.GitHubRepoName, input.NeptunCode, cancellationToken); + + var prUrl = input.GitHubPullRequestNum.HasValue + ? $"https://github.com/{Normalize.RepoName(input.GitHubRepoName)}/pull/{input.GitHubPullRequestNum}" + : null; + + var origin = string.IsNullOrEmpty(input.Origin) + ? $"https://github.com/{Normalize.RepoName(input.GitHubRepoName)}/commit/{input.GitHubCommitHash}" + : input.Origin; + + return await AddResultAsync(courseId, submission, Normalize.Neptun(input.NeptunCode), input.GitHubPullRequestNum, prUrl, + timestamp, AutomatedActor, origin, confirmed: false, AggregatePoints(input.Result), cancellationToken); + } + + /// + /// Sums task points per exercise name, ordered by name. Port of ResultProcessor.GetTotalPoints — + /// per-task detail is intentionally not persisted. + /// + internal static List<(string Name, double Point)> AggregatePoints(IReadOnlyList tasks) + { + if (tasks is null) + return new List<(string, double)>(); + + return tasks + .GroupBy(r => string.IsNullOrEmpty(r.ExerciseName) ? string.Empty : r.ExerciseName) + .Select(g => (Name: g.Key, Point: g.Sum(r => r.Points))) + .OrderBy(x => x.Name, StringComparer.Ordinal) + .ToList(); + } + + /// + /// Positional values keep the previous result's exercise names where available, otherwise "ex{i}". + /// Port of SetGradeService.getPoints. + /// + internal static List<(string Name, double Point)> BuildPoints(IReadOnlyList values, ICollection? previousPoints) + { + var previous = previousPoints?.OrderBy(p => p.Order).ToList(); + var result = new List<(string, double)>(values.Count); + + for (var i = 0; i < values.Count; i++) + { + var name = previous is not null && previous.Count > i ? previous[i].Name : $"ex{i}"; + result.Add((name, values[i])); + } + + return result; + } + + private Task GetLastResultAsync(int courseId, int submissionId, int? prNumber, CancellationToken cancellationToken) + => db.GradeRecords + .IgnoreQueryFilters() + .Include(g => g.Points) + .Where(g => g.CourseId == courseId && g.SubmissionId == submissionId && g.PrNumber == prNumber) + .OrderByDescending(g => g.Date) + .FirstOrDefaultAsync(cancellationToken); + + private async Task AddResultAsync( + int courseId, Submission submission, string neptun, int? prNumber, string? prUrl, + DateTimeOffset date, string? actor, string? origin, bool confirmed, + List<(string Name, double Point)> points, CancellationToken cancellationToken) + { + var record = new GradeRecord + { + CourseId = courseId, + SubmissionId = submission.Id, + StudentId = submission.StudentId, + Neptun = neptun, + PrNumber = prNumber, + PrUrl = prUrl, + Date = date, + Actor = actor, + Origin = origin, + Confirmed = confirmed, + }; + + for (var i = 0; i < points.Count; i++) + record.Points.Add(new GradeExercisePoint { Name = points[i].Name, Point = points[i].Point, Order = i }); + + db.GradeRecords.Add(record); + + submission.LastEventAt = date; + await db.SaveChangesAsync(cancellationToken); + + return record; + } +} diff --git a/ahk-backend/Ahk.Web.Services/Health/CiCallbackTokenHealthCheck.cs b/ahk-backend/Ahk.Web.Services/Health/CiCallbackTokenHealthCheck.cs new file mode 100644 index 00000000..bd8b570b --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/Health/CiCallbackTokenHealthCheck.cs @@ -0,0 +1,52 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Microsoft.EntityFrameworkCore; + +namespace Ahk.Web.Services.Health; + +/// +/// Checks that the course can still receive evaluation results: publish-results-pr signs its callback with a +/// , and without a live one every evaluation is rejected. +/// +public sealed class CiCallbackTokenHealthCheck : ICourseHealthCheck +{ + private readonly ApplicationDbContext db; + + public CiCallbackTokenHealthCheck(ApplicationDbContext db) => this.db = db; + + public string Id => "ci-callback-token"; + + public string Title => "CI callback token"; + + public int Order => 30; + + public async Task RunAsync(Course course, CancellationToken cancellationToken = default) + { + // IgnoreQueryFilters: health checks run in the host/admin context, where no current course is set and + // the course filter would otherwise match nothing. + var tokens = await db.CourseWebhookTokens + .IgnoreQueryFilters() + .AsNoTracking() + .Where(t => t.CourseId == course.Id) + .Select(t => new { t.RevokedAt }) + .ToListAsync(cancellationToken); + + var active = tokens.Count(t => t.RevokedAt is null); + if (active > 0) + { + return HealthCheckResult.Healthy( + this, + active == 1 ? "One active token accepts evaluation results." : $"{active} active tokens accept evaluation results."); + } + + return tokens.Count == 0 + ? HealthCheckResult.NotConfigured( + this, + "No callback token exists, so evaluation results from GitHub Actions will be rejected.", + "Create a token under CI callback tokens and set it on the course's evaluator workflow.") + : HealthCheckResult.Failed( + this, + "Every callback token for this course has been revoked, so evaluation results are being rejected.", + "Create a replacement token and update the course's evaluator workflow."); + } +} diff --git a/ahk-backend/Ahk.Web.Services/Health/CourseHealthModels.cs b/ahk-backend/Ahk.Web.Services/Health/CourseHealthModels.cs new file mode 100644 index 00000000..3d2db465 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/Health/CourseHealthModels.cs @@ -0,0 +1,89 @@ +namespace Ahk.Web.Services.Health; + +/// Outcome of a single health check. Ordered by severity so a report can take the worst. +public enum HealthStatus +{ + /// The check had nothing to verify (an optional setting is not in use). + NotConfigured = 0, + + /// The check passed. + Healthy = 1, + + /// The check passed, but something needs attention before it becomes a failure. + Warning = 2, + + /// The check failed — this part of the course's integration will not work. + Failed = 3, +} + +/// Result of one run against one course. +public sealed class HealthCheckResult +{ + /// Stable identifier of the check that produced this result (). + public string CheckId { get; init; } = string.Empty; + + /// Human-readable name of the check, e.g. "GitHub access token". + public string Title { get; init; } = string.Empty; + + public HealthStatus Status { get; init; } + + /// One sentence stating what was found. Shown verbatim in the admin UI. + public string Message { get; init; } = string.Empty; + + /// Optional next step when the check did not pass. + public string? Remediation { get; init; } + + public int DurationMs { get; init; } + + public static HealthCheckResult Healthy(ICourseHealthCheck check, string message) => + Create(check, HealthStatus.Healthy, message, null); + + public static HealthCheckResult Warning(ICourseHealthCheck check, string message, string? remediation = null) => + Create(check, HealthStatus.Warning, message, remediation); + + public static HealthCheckResult Failed(ICourseHealthCheck check, string message, string? remediation = null) => + Create(check, HealthStatus.Failed, message, remediation); + + public static HealthCheckResult NotConfigured(ICourseHealthCheck check, string message, string? remediation = null) => + Create(check, HealthStatus.NotConfigured, message, remediation); + + private static HealthCheckResult Create(ICourseHealthCheck check, HealthStatus status, string message, string? remediation) => new() + { + CheckId = check.Id, + Title = check.Title, + Status = status, + Message = message, + Remediation = remediation, + }; +} + +/// All check results for one course, plus the aggregate status the course list shows. +public sealed class CourseHealthReport +{ + public int CourseId { get; init; } + + public string CourseSlug { get; init; } = string.Empty; + + public string CourseName { get; init; } = string.Empty; + + public DateTimeOffset CheckedAt { get; init; } = DateTimeOffset.UtcNow; + + public IReadOnlyList Checks { get; init; } = Array.Empty(); + + /// + /// The worst status across the checks. results do not drag the + /// aggregate down on their own — a course with nothing wired up yet is incomplete, not broken — but a + /// report made up entirely of them reports . + /// + public HealthStatus Status + { + get + { + if (Checks.Count == 0) + return HealthStatus.NotConfigured; + + var worst = Checks.Max(c => c.Status); + return worst; + } + } +} diff --git a/ahk-backend/Ahk.Web.Services/Health/CourseHealthService.cs b/ahk-backend/Ahk.Web.Services/Health/CourseHealthService.cs new file mode 100644 index 00000000..953b800f --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/Health/CourseHealthService.cs @@ -0,0 +1,91 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Microsoft.EntityFrameworkCore; + +namespace Ahk.Web.Services.Health; + +public interface ICourseHealthService +{ + /// Runs every registered check against one course. Returns null when the course does not exist. + Task CheckCourseAsync(int courseId, CancellationToken cancellationToken = default); + + /// Runs every registered check against every course. + Task> CheckAllCoursesAsync(CancellationToken cancellationToken = default); +} + +/// +/// Runs the registered s and assembles the reports the admin dashboard shows. +/// +/// Courses are checked sequentially: the checks share the request's , which is +/// not thread-safe, and the only slow check () is bounded by its own +/// 10-second HTTP timeout. +/// +public sealed class CourseHealthService : ICourseHealthService +{ + private readonly ApplicationDbContext db; + private readonly IReadOnlyList checks; + + public CourseHealthService(ApplicationDbContext db, IEnumerable checks) + { + this.db = db; + this.checks = checks.OrderBy(c => c.Order).ThenBy(c => c.Id, StringComparer.Ordinal).ToList(); + } + + public async Task CheckCourseAsync(int courseId, CancellationToken cancellationToken = default) + { + var course = await LoadCourses().FirstOrDefaultAsync(c => c.Id == courseId, cancellationToken); + return course is null ? null : await RunChecksAsync(course, cancellationToken); + } + + public async Task> CheckAllCoursesAsync(CancellationToken cancellationToken = default) + { + var courses = await LoadCourses().OrderBy(c => c.Slug).ToListAsync(cancellationToken); + + var reports = new List(courses.Count); + foreach (var course in courses) + reports.Add(await RunChecksAsync(course, cancellationToken)); + + return reports; + } + + private IQueryable LoadCourses() => db.Courses.AsNoTracking().Include(c => c.GitHubConfig); + + private async Task RunChecksAsync(Course course, CancellationToken cancellationToken) + { + var results = new List(checks.Count); + + foreach (var check in checks) + { + var started = DateTimeOffset.UtcNow; + HealthCheckResult result; + try + { + result = await check.RunAsync(course, cancellationToken); + } + catch (Exception ex) when (ex is not OperationCanceledException) + { + // A check is not allowed to take the dashboard down with it. + result = HealthCheckResult.Failed(check, $"The check could not complete: {ex.Message}"); + } + + var elapsed = (int)(DateTimeOffset.UtcNow - started).TotalMilliseconds; + results.Add(new HealthCheckResult + { + CheckId = result.CheckId, + Title = result.Title, + Status = result.Status, + Message = result.Message, + Remediation = result.Remediation, + DurationMs = elapsed, + }); + } + + return new CourseHealthReport + { + CourseId = course.Id, + CourseSlug = course.Slug, + CourseName = course.Name, + Checks = results, + }; + } +} diff --git a/ahk-backend/Ahk.Web.Services/Health/GitHubAccessHealthCheck.cs b/ahk-backend/Ahk.Web.Services/Health/GitHubAccessHealthCheck.cs new file mode 100644 index 00000000..44526989 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/Health/GitHubAccessHealthCheck.cs @@ -0,0 +1,118 @@ +using System.Net; +using System.Net.Http.Headers; +using System.Text.Json; +using Ahk.Web.Data.Entities; + +namespace Ahk.Web.Services.Health; + +/// +/// Verifies that the course's GitHub access token still works and reaches the course's organization. +/// Two calls, both cheap: GET /user proves the token is valid, GET /orgs/{org} proves it can see +/// the organization the course's repositories live in. +/// +/// This is the only check that leaves the process, so it carries its own short timeout — the admin dashboard +/// runs it for every course at once and must stay responsive when GitHub is slow. +/// +public sealed class GitHubAccessHealthCheck : ICourseHealthCheck +{ + /// Named registered by AddAhkServices. + public const string HttpClientName = "github-health"; + + private readonly IHttpClientFactory httpClientFactory; + + public GitHubAccessHealthCheck(IHttpClientFactory httpClientFactory) => this.httpClientFactory = httpClientFactory; + + public string Id => "github-access-token"; + + public string Title => "GitHub access token"; + + public int Order => 20; + + public async Task RunAsync(Course course, CancellationToken cancellationToken = default) + { + var token = course.GitHubConfig?.GitHubAccessToken; + if (string.IsNullOrWhiteSpace(token)) + { + return HealthCheckResult.NotConfigured( + this, + "No access token is stored for this course.", + "Add a token under GitHub integration to let the portal talk to GitHub."); + } + + using var client = httpClientFactory.CreateClient(HttpClientName); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); + + var (identity, failure) = await GetLoginAsync(client, "user", cancellationToken); + if (failure is not null) + return failure; + + if (string.IsNullOrWhiteSpace(course.GitHubOrganization)) + { + return HealthCheckResult.Warning( + this, + $"The token is valid (authenticated as {identity}), but the course has no GitHub organization to check against.", + "Set the course's GitHub organization so repository access can be verified."); + } + + var (org, orgFailure) = await GetLoginAsync(client, $"orgs/{Uri.EscapeDataString(course.GitHubOrganization)}", cancellationToken); + if (orgFailure is not null) + { + // A valid token that cannot see the org is the interesting failure: report both facts. + return HealthCheckResult.Failed( + this, + $"The token is valid (authenticated as {identity}) but cannot read the organization '{course.GitHubOrganization}'. {orgFailure.Message}", + $"Grant the token access to '{course.GitHubOrganization}', or correct the organization on the course."); + } + + return HealthCheckResult.Healthy(this, $"Authenticated as {identity}; organization '{org}' is reachable."); + } + + /// + /// Calls a GitHub endpoint and returns its login field. The failure result is returned rather than + /// thrown so a single unreachable course cannot fail the whole dashboard. + /// + private async Task<(string? Login, HealthCheckResult? Failure)> GetLoginAsync(HttpClient client, string path, CancellationToken cancellationToken) + { + try + { + using var response = await client.GetAsync(path, cancellationToken); + + if (!response.IsSuccessStatusCode) + return (null, HealthCheckResult.Failed(this, DescribeFailure(response.StatusCode), RemediationFor(response.StatusCode))); + + await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken); + using var document = await JsonDocument.ParseAsync(stream, cancellationToken: cancellationToken); + + var login = document.RootElement.TryGetProperty("login", out var value) ? value.GetString() : null; + return (login ?? "unknown", null); + } + catch (TaskCanceledException) when (!cancellationToken.IsCancellationRequested) + { + return (null, HealthCheckResult.Failed(this, "GitHub did not respond within 10 seconds.", "Check network access from the server to api.github.com.")); + } + catch (HttpRequestException ex) + { + return (null, HealthCheckResult.Failed(this, $"GitHub could not be reached: {ex.Message}", "Check network access from the server to api.github.com.")); + } + catch (JsonException) + { + return (null, HealthCheckResult.Failed(this, "GitHub returned a response the portal could not read.", "Retry; if it persists, check whether the API base address is correct.")); + } + } + + private static string DescribeFailure(HttpStatusCode status) => status switch + { + HttpStatusCode.Unauthorized => "GitHub rejected the token (401). It is invalid, revoked or expired.", + HttpStatusCode.Forbidden => "GitHub refused the request (403). The token lacks the required scope, or the rate limit is exhausted.", + HttpStatusCode.NotFound => "GitHub returned 404. The organization does not exist, or the token cannot see it.", + _ => $"GitHub returned {(int)status} {status}.", + }; + + private static string RemediationFor(HttpStatusCode status) => status switch + { + HttpStatusCode.Unauthorized => "Issue a new access token and save it under GitHub integration.", + HttpStatusCode.Forbidden => "Give the token the read:org and repo scopes, then try again.", + HttpStatusCode.NotFound => "Check the organization name on the course and the token's access to it.", + _ => "Retry the check; if it persists, verify the token on GitHub.", + }; +} diff --git a/ahk-backend/Ahk.Web.Services/Health/ICourseHealthCheck.cs b/ahk-backend/Ahk.Web.Services/Health/ICourseHealthCheck.cs new file mode 100644 index 00000000..0bd7fa9c --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/Health/ICourseHealthCheck.cs @@ -0,0 +1,26 @@ +using Ahk.Web.Data.Entities; + +namespace Ahk.Web.Services.Health; + +/// +/// One verifiable property of a course's integration. Implementations are registered in DI and run by +/// ; adding a check to the admin dashboard means adding one class and one +/// registration line — nothing else changes. +/// +public interface ICourseHealthCheck +{ + /// Stable machine identifier, e.g. "github-access-token". Used as the result key. + string Id { get; } + + /// Short name shown as the check's label in the admin UI. + string Title { get; } + + /// Order within a course's report; lower runs and displays first. + int Order { get; } + + /// + /// Runs the check. The is loaded with its . + /// Implementations must not throw: return a result instead. + /// + Task RunAsync(Course course, CancellationToken cancellationToken = default); +} diff --git a/ahk-backend/Ahk.Web.Services/Health/WebhookConfigurationHealthCheck.cs b/ahk-backend/Ahk.Web.Services/Health/WebhookConfigurationHealthCheck.cs new file mode 100644 index 00000000..1d6a79af --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/Health/WebhookConfigurationHealthCheck.cs @@ -0,0 +1,48 @@ +using Ahk.Web.Data.Entities; + +namespace Ahk.Web.Services.Health; + +/// +/// Checks the settings the GitHub webhook receiver will need: an organization to resolve incoming deliveries +/// to this course, and a secret to validate their X-Hub-Signature-256 header. Local check, no network. +/// +public sealed class WebhookConfigurationHealthCheck : ICourseHealthCheck +{ + public string Id => "github-webhook-config"; + + public string Title => "Webhook settings"; + + public int Order => 10; + + public Task RunAsync(Course course, CancellationToken cancellationToken = default) + { + if (string.IsNullOrWhiteSpace(course.GitHubOrganization)) + { + return Task.FromResult(HealthCheckResult.NotConfigured( + this, + "The course has no GitHub organization, so incoming deliveries cannot be routed to it.", + "Set the GitHub organization on the course's general settings.")); + } + + var config = course.GitHubConfig; + if (config is null || string.IsNullOrWhiteSpace(config.GitHubWebhookSecret)) + { + return Task.FromResult(HealthCheckResult.Warning( + this, + $"Deliveries route to '{course.GitHubOrganization}', but no webhook secret is stored, so their signature cannot be validated.", + "Paste the secret configured on the GitHub App into GitHub integration.")); + } + + if (!config.Enabled) + { + return Task.FromResult(HealthCheckResult.Warning( + this, + "The integration is turned off — the portal will ignore this course's webhooks.", + "Turn the integration back on under GitHub integration.")); + } + + return Task.FromResult(HealthCheckResult.Healthy( + this, + $"Deliveries from '{course.GitHubOrganization}' route to this course and their signature is validated.")); + } +} diff --git a/ahk-backend/Ahk.Web.Services/ServiceCollectionExtensions.cs b/ahk-backend/Ahk.Web.Services/ServiceCollectionExtensions.cs new file mode 100644 index 00000000..2e892f1b --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/ServiceCollectionExtensions.cs @@ -0,0 +1,53 @@ +using System.Net.Http.Headers; +using Ahk.Web.Services.Courses; +using Ahk.Web.Services.Grading; +using Ahk.Web.Services.Health; +using Ahk.Web.Services.StatusTracking; +using Ahk.Web.Services.Submissions; +using Microsoft.Extensions.DependencyInjection; + +namespace Ahk.Web.Services; + +public static class ServiceCollectionExtensions +{ + /// Registers the domain services. All are scoped: they use the request's ApplicationDbContext. + public static IServiceCollection AddAhkServices(this IServiceCollection services) + { + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + + services.AddAhkCourseHealthChecks(); + + return services; + } + + /// + /// Registers the course health checks and the service that runs them. Adding a check to the admin + /// dashboard is one line here plus the class itself — the service discovers checks through DI. + /// + public static IServiceCollection AddAhkCourseHealthChecks(this IServiceCollection services) + { + services.AddHttpClient(GitHubAccessHealthCheck.HttpClientName, client => + { + client.BaseAddress = new Uri("https://api.github.com/"); + client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("ahk-portal", "1.0")); + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.github+json")); + client.DefaultRequestHeaders.Add("X-GitHub-Api-Version", "2022-11-28"); + + // The admin dashboard checks every course in one request; a hung call must not hold it open. + client.Timeout = TimeSpan.FromSeconds(10); + }); + + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + + return services; + } +} diff --git a/ahk-backend/Ahk.Web.Services/StatusTracking/Dto/RepositoryStatus.cs b/ahk-backend/Ahk.Web.Services/StatusTracking/Dto/RepositoryStatus.cs new file mode 100644 index 00000000..45345b82 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/StatusTracking/Dto/RepositoryStatus.cs @@ -0,0 +1,39 @@ +namespace Ahk.Web.Services.StatusTracking.Dto; + +/// +/// Projected current state of one submission, derived from its append-only event log. Shape preserved from the +/// original grade-management/.../StatusTracking/Dto/RepositoryStatus.cs so the teacher dashboard renders +/// the same information. +/// +public sealed class RepositoryStatus +{ + public string Repository { get; set; } = string.Empty; + + public string Neptun { get; set; } = string.Empty; + + public IReadOnlyCollection Branches { get; set; } = Array.Empty(); + + public IReadOnlyCollection PullRequests { get; set; } = Array.Empty(); + + public WorkflowRunsStatus WorkflowRuns { get; set; } = new(); +} + +public sealed class PullRequestStatus +{ + public int Number { get; set; } + + public string? HtmlUrl { get; set; } + + /// The most recent action seen for this pull request. + public string? Status { get; set; } + + /// Distinct assignees across the PR's events, comma-joined (as in the original implementation). + public string? Assignee { get; set; } +} + +public sealed class WorkflowRunsStatus +{ + public int Count { get; set; } + + public string? LastStatus { get; set; } +} diff --git a/ahk-backend/Ahk.Web.Services/StatusTracking/StatusTrackingService.cs b/ahk-backend/Ahk.Web.Services/StatusTracking/StatusTrackingService.cs new file mode 100644 index 00000000..c9f4f78d --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/StatusTracking/StatusTrackingService.cs @@ -0,0 +1,85 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Ahk.Web.Services.StatusTracking.Dto; +using Microsoft.EntityFrameworkCore; + +namespace Ahk.Web.Services.StatusTracking; + +public interface IStatusTrackingService +{ + Task> ListStatusesAsync(int courseId, CancellationToken cancellationToken = default); +} + +/// +/// Projects the append-only log into the per-submission status view. +/// Port of grade-management/.../StatusTracking/StatusTrackingService.cs: the grouping and +/// "latest event wins" rules are preserved exactly, with the repo-prefix filter replaced by the course id. +/// +public sealed class StatusTrackingService : IStatusTrackingService +{ + private readonly ApplicationDbContext db; + + public StatusTrackingService(ApplicationDbContext db) => this.db = db; + + public async Task> ListStatusesAsync(int courseId, CancellationToken cancellationToken = default) + { + var submissions = await db.Submissions + .IgnoreQueryFilters() + .AsNoTracking() + .Where(s => s.CourseId == courseId) + .Include(s => s.Events) + .Include(s => s.Student) + .ToListAsync(cancellationToken); + + return submissions.Select(CreateStatus).ToList(); + } + + private static RepositoryStatus CreateStatus(Submission submission) + { + var events = submission.Events; + + return new RepositoryStatus + { + Repository = submission.GitHubRepoName, + Neptun = GetNeptun(submission, events), + Branches = events.OfType().Select(e => e.Branch).Distinct().ToArray(), + PullRequests = events.OfType() + .GroupBy(e => e.Number) + .Select(GetPrStatus) + .ToArray(), + WorkflowRuns = GetWorkflowRunsStatus(events), + }; + } + + /// Latest non-empty neptun from the PR events, falling back to the linked student. + private static string GetNeptun(Submission submission, IEnumerable events) + => events.OfType() + .Where(e => !string.IsNullOrEmpty(e.Neptun)) + .OrderByDescending(e => e.Timestamp) + .Select(e => e.Neptun!) + .FirstOrDefault() + ?? submission.Student?.Neptun + ?? string.Empty; + + private static PullRequestStatus GetPrStatus(IGrouping events) + { + var latest = events.OrderByDescending(e => e.Timestamp).First(); + return new PullRequestStatus + { + Number = events.Key, + HtmlUrl = latest.HtmlUrl, + Status = latest.Action, + Assignee = string.Join(", ", events.SelectMany(e => e.Assignees).Distinct()), + }; + } + + private static WorkflowRunsStatus GetWorkflowRunsStatus(IEnumerable events) + { + var items = events.OfType().ToList(); + return new WorkflowRunsStatus + { + Count = items.Count, + LastStatus = items.OrderByDescending(e => e.Timestamp).FirstOrDefault()?.Conclusion, + }; + } +} diff --git a/ahk-backend/Ahk.Web.Services/StatusTracking/SubmissionEventService.cs b/ahk-backend/Ahk.Web.Services/StatusTracking/SubmissionEventService.cs new file mode 100644 index 00000000..ad657eda --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/StatusTracking/SubmissionEventService.cs @@ -0,0 +1,57 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Ahk.Web.Services.Submissions; +using Microsoft.EntityFrameworkCore; + +namespace Ahk.Web.Services.StatusTracking; + +public interface ISubmissionEventService +{ + /// + /// Appends a status event. Returns false when the event was a webhook redelivery and was skipped. + /// + Task RecordAsync(int courseId, string gitHubRepoName, SubmissionEvent submissionEvent, string? neptun = null, CancellationToken cancellationToken = default); +} + +/// +/// Appends to the status event log (was StatusTrackingService.InsertNewEvent plus the queue plumbing). +/// Resolves the submission first, so events and grades share the same anchor row. +/// +public sealed class SubmissionEventService : ISubmissionEventService +{ + private readonly ApplicationDbContext db; + private readonly ISubmissionResolver submissions; + + public SubmissionEventService(ApplicationDbContext db, ISubmissionResolver submissions) + { + this.db = db; + this.submissions = submissions; + } + + public async Task RecordAsync(int courseId, string gitHubRepoName, SubmissionEvent submissionEvent, string? neptun = null, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(submissionEvent); + + // GitHub redelivers webhooks; the delivery id makes appending idempotent. + if (!string.IsNullOrEmpty(submissionEvent.GitHubDeliveryId)) + { + var alreadySeen = await db.SubmissionEvents.IgnoreQueryFilters() + .AnyAsync(e => e.GitHubDeliveryId == submissionEvent.GitHubDeliveryId, cancellationToken); + if (alreadySeen) + return false; + } + + var submission = await submissions.GetOrCreateAsync(courseId, gitHubRepoName, neptun, cancellationToken); + + submissionEvent.CourseId = courseId; + submissionEvent.SubmissionId = submission.Id; + if (submissionEvent.Timestamp == default) + submissionEvent.Timestamp = DateTimeOffset.UtcNow; + + db.SubmissionEvents.Add(submissionEvent); + submission.LastEventAt = submissionEvent.Timestamp; + + await db.SaveChangesAsync(cancellationToken); + return true; + } +} diff --git a/ahk-backend/Ahk.Web.Services/Submissions/SubmissionResolver.cs b/ahk-backend/Ahk.Web.Services/Submissions/SubmissionResolver.cs new file mode 100644 index 00000000..03fa919a --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/Submissions/SubmissionResolver.cs @@ -0,0 +1,67 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Microsoft.EntityFrameworkCore; + +namespace Ahk.Web.Services.Submissions; + +public interface ISubmissionResolver +{ + Task GetOrCreateAsync(int courseId, string gitHubRepoName, string? neptun = null, CancellationToken cancellationToken = default); + + Task GetOrCreateStudentAsync(int courseId, string neptun, CancellationToken cancellationToken = default); +} + +/// +/// Resolves the (student, submission) pair every write path needs. In the original system these were just +/// normalized strings on each record; here they are rows, created on first sighting. +/// +/// Queries use IgnoreQueryFilters and filter on the explicit because callers +/// include machine-to-machine paths (webhooks, CI callbacks) that resolve their course from a payload or token +/// rather than the route, and must not depend on the ambient course context. +/// +public sealed class SubmissionResolver : ISubmissionResolver +{ + private readonly ApplicationDbContext db; + + public SubmissionResolver(ApplicationDbContext db) => this.db = db; + + public async Task GetOrCreateStudentAsync(int courseId, string neptun, CancellationToken cancellationToken = default) + { + var normalized = Normalize.Neptun(neptun); + + var student = await db.Students.IgnoreQueryFilters() + .FirstOrDefaultAsync(s => s.CourseId == courseId && s.Neptun == normalized, cancellationToken); + + if (student is not null) + return student; + + student = new Student { CourseId = courseId, Neptun = normalized }; + db.Students.Add(student); + await db.SaveChangesAsync(cancellationToken); + return student; + } + + public async Task GetOrCreateAsync(int courseId, string gitHubRepoName, string? neptun = null, CancellationToken cancellationToken = default) + { + var repo = Normalize.RepoName(gitHubRepoName); + + var submission = await db.Submissions.IgnoreQueryFilters() + .FirstOrDefaultAsync(s => s.CourseId == courseId && s.GitHubRepoName == repo, cancellationToken); + + if (submission is null) + { + submission = new Submission { CourseId = courseId, GitHubRepoName = repo }; + db.Submissions.Add(submission); + } + + // The repository usually exists before neptun.txt is pushed, so link the student opportunistically. + if (!string.IsNullOrWhiteSpace(neptun) && submission.StudentId is null) + { + var student = await GetOrCreateStudentAsync(courseId, neptun, cancellationToken); + submission.StudentId = student.Id; + } + + await db.SaveChangesAsync(cancellationToken); + return submission; + } +} diff --git a/ahk-backend/Ahk.Web.slnx b/ahk-backend/Ahk.Web.slnx index 27d07430..24ec34ad 100644 --- a/ahk-backend/Ahk.Web.slnx +++ b/ahk-backend/Ahk.Web.slnx @@ -1,5 +1,7 @@ + + diff --git a/ahk-backend/README.md b/ahk-backend/README.md index 74892678..410f3272 100644 --- a/ahk-backend/README.md +++ b/ahk-backend/README.md @@ -5,19 +5,23 @@ per-course Azure Functions deployments with a single site whose domain data is a **Courses**. Provides ASP.NET Identity authentication (local username/password + generic OIDC, cookie-based) and course-scoped, membership-authorized endpoints. -> Skeleton milestone: auth + course-scoping plumbing + OpenAPI. The github-monitor / -> grade-management functionality is ported in a later milestone. See the architecture plan for the -> full design. +> Milestone status: auth, course-scoping, the domain model and services, the read endpoints, and the +> site administration surface (courses, GitHub integration, CI callback tokens, users, health checks) +> are in place. The write-side entry points — the GitHub webhook receiver, `/ahk ok` chatops and the +> HMAC-verified CI callback — are ported in a later milestone. See the architecture plan for the full +> design. ## Projects - **Ahk.Web.Server** — Web API host: `Program.cs` wiring, `Auth/` (local + OIDC controllers), - `Admin/` (host-context course management), `Courses/` (course-context endpoints), + `Admin/` (host-context course, user and health management), `Courses/` (course-context endpoints), `CourseContext/` (course resolution middleware + membership authorization). +- **Ahk.Web.Services** — domain logic: grading, status tracking, submission resolution, course + resolution, CI callback tokens, and `Health/` (the course health checks). - **Ahk.Web.Data** — EF Core `ApplicationDbContext` (Identity + `Course`/`CourseMembership` + `ICourseScoped` global query filter), migrations, and the dev data seeder. -- **Ahk.Web.Server.Tests** — xUnit tests (course-scoping unit tests + API smoke tests via - `WebApplicationFactory`). +- **Ahk.Web.Server.Tests** — xUnit tests (course-scoping unit tests, health-check tests, grade parity + tests + API smoke tests via `WebApplicationFactory`). ## Run @@ -36,19 +40,103 @@ Dev data seeder (Development env only) creates: - site admin — `admin` / `Admin123!` - instructor (member of `viaubc01` only) — `instructor` / `Instructor123!` -- sample courses `viaubc01`, `viaubb01` +- sample courses `viaubc01`, `viaubb01` — deliberately configured differently so the health dashboard + shows a mix of states -## Configuration (`AHK`-style keys under `Authentication`/`ConnectionStrings`) +## Configuration (keys under `Authentication`/`ConnectionStrings`) - `ConnectionStrings:Default` — MSSQL connection string. -- `Authentication:Oidc:{Authority,ClientId,ClientSecret,Scopes}` — generic OIDC provider. When - `Authority`/`ClientId` are empty, OIDC is disabled and the app runs with local login only. +- `Authentication:Oidc:*` — OIDC provider. When `Authority`/`ClientId` are empty, OIDC is disabled and + the app runs with local login only. + +### OIDC against the BME IdP + +Registered as client `AUTAhkClient` at `https://idp.bme.hu` (Shibboleth). The defaults in +`Configuration/OidcOptions.cs` encode constraints of that provider — changing them breaks login: + +| Setting | Value | Why | +|---|---|---| +| `Scopes` | `openid email userinfo` | Exactly what is registered; `profile` is **not** registered | +| `UsePkce` | `false` | IdP does not advertise `code_challenge_methods_supported` | +| `ResponseMode` | `query` | `form_post` would drop the correlation cookie (SameSite=Lax) | +| `EndSessionEndpoint` | empty | IdP advertises none → logout is local-only | + +`neptun_code` and `eduperson_scoped_affiliation` arrive from the **userinfo** endpoint and are mapped +explicitly in `Program.cs` (ASP.NET maps no standard claims by default), then persisted onto +`ApplicationUser` by `Auth/ExternalClaimsMapper.cs` on every login. + +**The client secret is never committed**: use `dotnet user-secrets set "Authentication:Oidc:ClientSecret" "…"` +locally and the `Authentication__Oidc__ClientSecret` environment variable in production. + +### Local OIDC development + +Only the production redirect URI (`https://ahk.aut.bme.hu/signin-oidc`) is registered, so localhost +cannot talk to the real IdP. Development instead uses the in-app mock provider (`MockOidc/`), enabled by +`Authentication:Oidc:UseMockProvider` — it serves discovery/authorize/token/userinfo/JWKS under +`/mock-oidc` and signs real RS256 id_tokens, so the genuine validation path is exercised. + +```bash +# choose which fixed persona the next login returns +curl -k "https://localhost:7443/mock-oidc/persona?user=student" # instructor | student | noclaims +``` + +## Site administration API + +All under `/api/admin/...`, all requiring the site-level `Admin` role. This is the surface the SPA's +admin console is built on. + +| Route | Purpose | +|---|---| +| `GET/POST /courses`, `GET/PUT/DELETE /courses/{id}` | The course register. `DELETE` requires `?confirmSlug=` to match, and cascades to the course's students, submissions, events, grades, tokens and staff | +| `GET/PUT /courses/{id}/github` | GitHub integration: App ID + private key, access token, webhook secret, workflow-run limit, on/off | +| `GET/PUT/DELETE /courses/{id}/members[/{userId}]` | Course staff and the role each holds | +| `GET/POST/DELETE /courses/{id}/tokens[/{tokenId}]` | CI callback tokens. The creating response is the only place a token's secret appears | +| `GET /users`, `POST /users`, `GET/PUT/DELETE /users/{id}` | Accounts. Search by name/username/email/Neptun, filter by course | +| `PUT /users/{id}/roles` | Site roles. An admin cannot remove their own `Admin` role | +| `PUT/DELETE /users/{id}/courses[/{courseId}]` | Course assignments | +| `POST /users/{id}/password` | Set a local account's password | +| `GET /health`, `GET /health/{courseId}` | Run the course health checks | + +**Stored credentials are never returned.** The GitHub config DTO reports only whether each credential +is present (plus a last-four hint for the access token). On update, each credential field follows one +rule: `null` leaves the stored value alone, `""` clears it, anything else replaces it — so saving an +untouched form cannot wipe a secret the browser was never shown. + +## Course health checks + +`Ahk.Web.Services/Health/` answers "is this course's integration actually wired up?". Each check is an +`ICourseHealthCheck` registered in DI and discovered by `CourseHealthService`, so **adding a check is +one class plus one registration line** — the controller and the UI need no change. + +| Check | What it verifies | +|---|---| +| `github-webhook-config` | The course has an organization to route deliveries from, a secret to validate their signature, and the integration is on. Local | +| `github-access-token` | `GET /user` and `GET /orgs/{org}` against api.github.com with the stored token. Network, 10s timeout | +| `ci-callback-token` | At least one non-revoked `CourseWebhookToken` exists, so evaluation results are still accepted | + +Results carry a status (`Healthy` / `Warning` / `Failed` / `NotConfigured`), a message, and a +remediation line; a course's overall status is the worst of its checks. Checks must not throw — a +failure is a `Failed` result, so one unreachable course cannot take the dashboard down. ## Auth model - Cookie-based ASP.NET Identity (the API returns 401/403 rather than redirecting). We intentionally do **not** use `MapIdentityApi` — see the architecture plan for the rationale (no OIDC support, bearer-token focus, fixed shapes). +- **The auth cookies are named `ahk.auth` / `ahk.auth.external`** (`Program.ApplicationCookieName`), + not the framework defaults. Browsers scope cookies by host and ignore the port, so on `localhost` + every ASP.NET Identity app would otherwise share `.AspNetCore.Identity.Application`; a cookie from + another project carrying a GUID user id crashes this int-keyed app inside `SecurityStampValidator`, + 500-ing every request including login. `OnValidatePrincipal` additionally wraps the stamp validator + so an unreadable cookie signs the caller out rather than throwing. Do not revert either. +- `POST /api/auth/login` distinguishes its failures: the 401 body carries a `LoginFailureResponse` + with `reason` = `InvalidCredentials` / `LockedOut` / `NotAllowed`. Sign-in uses + `lockoutOnFailure: true`, so five wrong attempts lock the account for five minutes — without the + distinction that is indistinguishable from a typo. - Course context: `/api/{course}/...` routes are resolved to a `Course` and gated by the `CourseMember` policy. Host/admin routes live under `/api/admin/...`. Machine-to-machine webhook endpoints (added in the port) resolve their course from the payload/token, not the path segment. +- **Site admins can open any course.** `CourseMembershipAuthorizationHandler` grants the + `CourseMember` policy to the `Admin` role, and `GET /api/auth/me` therefore lists *every* course for + an admin — marked `viaSiteAdmin: true` where there is no membership record — so the SPA's course + switcher and route guard need no special case for them. diff --git a/ahk-frontend/README.md b/ahk-frontend/README.md index e54bb3f6..83b8f123 100644 --- a/ahk-frontend/README.md +++ b/ahk-frontend/README.md @@ -4,8 +4,8 @@ Angular 21 SPA (teacher portal) for `ahk.aut.bme.hu`, talking to **ahk-backend** components + signals. Cookie-based auth; in dev the SPA and API are made same-origin by a proxy so **no CORS** is needed. -> Skeleton milestone: login (local + OIDC), a host/admin course-management screen, and a -> course-scoped dashboard that exercises course isolation. Real dashboards land in the port. +> Screens today: sign-in (local + BME SSO), the site administration console (courses, per-course +> GitHub integration, CI callback tokens, staff, users, health), and the course submissions dashboard. ## Structure @@ -13,8 +13,19 @@ components + signals. Cookie-based auth; in dev the SPA and API are made same-or `npm run generate-api`). - `src/app/core/auth/` — `AuthService` (session signals), functional guards, HTTP interceptor. - `src/app/core/course/` — active-course context + course membership guard. -- `src/app/layout/shell/` — authenticated app frame with course switcher. -- `src/app/features/` — `login/`, `admin/courses/`, `course/dashboard/`. +- `src/app/layout/shell/` — authenticated app frame: topbar with the course switcher, and a rail whose + contents follow the context (course screens vs. site administration). +- `src/app/shared/health-chain/` — a course's health drawn as the pipeline it describes. +- `src/app/features/` — `login/`, `no-access/`, `course/dashboard/`, and `admin/` (`courses/` with the + course editor, `users/`, `health/`). +- `src/styles.scss` — the design system, in the **BME AUT visual identity** (crimson Georgia headings, + Verdana body, parchment table headers). Component stylesheets are Angular-scoped, so tokens and the + shared classes (`page`, `card`, `field`, `btn`, `table.data`, `badge`, `notice`) all live here. Reach + for those before writing new component CSS. `--brand`/`--link`/`--bad` are three different reds on + purpose (see the comments in the file). +- `public/` — static assets served at `/`, including the department logos (`bme-aut-logo*.png`) and the + `eduid-logo.png` on the login button. These are derived copies; the masters and the palette's + provenance are in `brand/` (BME AUT identity pack + eduID logo), alongside this README. ## Run (dev, HTTPS) @@ -26,6 +37,25 @@ npm start # ng serve --ssl on https://localhost:4200, proxying /api → Start **ahk-backend** first (https://localhost:7443). Log in with a seeded account, e.g. `admin` / `Admin123!` or `instructor` / `Instructor123!`. +A single run: `npx ng test --watch=false`. + +## Signing in + +**eduID leads.** The login screen's primary action is the eduID button (a full-page navigation to +`/api/auth/external/challenge`); the local username/password form is collapsed behind an "I don't have +an eduID account" link and only appears when asked for. The button follows the +[eduID brand](https://eduid.hu/hu/depo/) but is rendered from the eduID logo plus an English "Login" +rather than shipping their Hungarian-label PNG. Its `--eduid` blue is scoped to `login.scss` and is +deliberately absent from the global palette. + +## Who sees what + +- **Site admins** land on `/admin/courses` and can open *any* course's instructor screens — the API + lists every course in `GET /api/auth/me` for them, so the course switcher and `courseGuard` need no + special case. Courses reached that way are marked in the rail, since the admin is not assigned staff. +- **Instructors** land on their first course. A signed-in user with no course assignment lands on + `/no-access`, which says who to ask, rather than being bounced back to the login form. + ## Regenerate the API client ```bash diff --git a/ahk-frontend/brand/BME-AUT logo english/BME_AUT_logo_BLACK-eng.eps b/ahk-frontend/brand/BME-AUT logo english/BME_AUT_logo_BLACK-eng.eps new file mode 100644 index 0000000000000000000000000000000000000000..063651fb94ce51c1e83ead67d4648c7a9e1fde3f GIT binary patch literal 488422 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

I$NG!O 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�N@>%embQuCm^Y-K1+}Rc|2;Rg-?T>s7+HYpNkj&MOq->z)e~#=qzSS}{ z5p5kS<7uDUrhilklNBp|6L^>4lS7v^Y>0{(^FeK1?IUOLM*%*9+4Q>KlkH)E<2=?i z#`nSHpgkxfiqu9IC)VLHd~EW~6LA)kaq-e1@dXBUSp{lwTdHtCWLi0?4I<;l+y4n~ zMP;mb-DBr{D$#IU+bBE684yHi8xve<224V1Nw?H9CIK5Mb$216;-K{N@)diN#r3`H zXd8Mp2UaOuRP8!i&!`1QW2r5fZVvRcg_?nykLDvmXdaCm8MQdfzesV@fGdjDJ^CvF z1zAKr^fi7!NUEIWIMD!9BHNCd!(e*hA~7ZHp+(U7M(k-J#mhm1NZeUjLniXa>ny$KFcW0QwOEq$~N4)in2wl#>>!SV; zRflapc)sjd0<)9vf%cuF&iLhag!MuN!WiMejYz?$(QHprn0aLWa1V5izK#%@*MDyOy(TKS8p|FKdg}!td^c|sRvyp~^hNyq_kPX&dmif9G; zaCGZqLjp@)6IxmM#^;2VI2FX)V1BT&v<#>I)o4PFMjjqJG?wM;ZK^_MeNqalNXAo= z%>6KFSD4T$V< zvo>Vlu5kRBPW%5fHMOIQbmz0mp07?6yWj>*V3d3a8`l@bFVd%wRbfDV1yTgUQmSZ+ z&Mq*V;}7rqxlHNeF`|xYWO$W9@eC@?nUHocd}T>xzBwo*oagmMZL9A@4&o&f>mw8i z!k-E6buMn&qC!TNQ36IT5YA3CARD5JyrZk3)$DiqFKn-;(2s*(lDgc8u zpbi2YzoYTEYc@;?kYQjGxkj)}Bp(0LdOF`%KtJoXbUUvxYY?qL-KR*6H~RjK9p>F& z;=-WRDA(%%9_p%xp<*B3Yh~n*fBekQsAt#RxvWxcRqclrV4&HXH7o}a0pCR;JOgE7 zodU9W@O&@sRwvFSDJU!;=-A~&c+9D6Xwj^UV>nO)?Lv&AJD*Gi7X@KC605EW?z^Ow zoS1c6VtfEmTvbyv!^U*kDG|lMm9<@IWKm zn{X^nr5GGvvdvB{8Cn{Udbf@1ymwtNae?V5#@+^5XjMJus;g^j@ME&^lEh!d8&s{e zf^(TnTZ7Kmp__s$5=i+bXw#ORqOMB|!{R&YR@~(0#-yJ%R8Dz4Vp_`K-dd%^Q7}KxB+xQT!Vz&Te#e%HF`@tq z2mB^m5>}#Xf_BsPQjyV&&;w73 zlooPlYT@jq88_?RjXBmzr=A@OtgRNtOu+DzsL-|{ zoc7yQ!^?`3{v(!fv^{OJsdX4a6D(!-dp&pqyx0MviC5nlb)112iF(rn{foQ&@L-Hl zgi0VP#YJpm{ApVXCo>2ysj~h&>v|{P(QD7YCm8t1`G+(}8Ap1>%O(e&)_Gh)FpuU2 z4QW0R&CscU_U-h*Z?l9ItavmV6*e{-qCnj6qlo06tRIOb`eupU(!uBbTCGtP#bkXJ z+>!+p*9x&z!!_b_5-Qsni{DP!**adcoTi<@AZ&zpOBfM&e0fIOP7{mjR*x+qv);pr z_k6rD31KCN6pc#v3$dHqPY7X1cY?=t11ovIj_WhewGfD*s_uF4HWg?^E4*5uz@~6zr|mfiW*QLd=h{b@sC5g{_ZAy-%8lZ%wP!qaZSXNq!)vG0yxpEwf$m!%4fvU=16 zvnj4nZR0{SiUei^J;KWj_sOV0EQ|%OGZ0zo?-hfCEMGIu7Ado=3b}z7$3Y2bcQGX4 z8=-KBbEK=ln&V?>CKJu^!loft$a?n&&FlCygn znY{@0ZKfL+D(OkknlT0-eM1(RLxxHl5|IVQrVEN{ zC_cB0XSYoT$iv#vwj3paAAm=7;l#zkRr|!Dh!@UShNd>f;|B^vcB*NdF~r`=Gh|u# z3ph{sJEH*uX1hz2_gA3kj1Sxqnwr3P`iEESSc_EzIDX$OeZnK7$-0Ep2ttq*^QPQ{ zUr3%aAru*B3Zik3fzZfG&pED>N`-tjygVlI=&K&|x78ZWsiaw9(a(iN7A3-hZW9I_ zeo!SXRs7aHZ29DxqDM>!?GNO8@hEVTRBjSCeF-KpA~W z@(L~VEj+N&KUdx(HEoq<8hGuCBwK?WE|%Efn_7isn$EI?PC6kX#4}Vfhy8T(ohhVF zsMt44&=g^kBEfx(RVBUR!+OQ-PDQqxJi)F@V#N|Wyw>@fzO5VYd~WH8&j z;Ix=g@!^UtaE7HU_gLiGS-ZH#v?*a#qRcfJjb^ktpx?wx4w@USDHiZd8tUw?h>@^` zR{qr~WK-$2bi0=-^m5rA0&@SLIc~gT!git>VE;Pk5yQ=`;z-NcVX_*?zxac|+pDD2 zs0MeM1JN`enV60j32nbO)K9}I?ioWfqBJm01yf0y(WW1!HAgpo^L=5=-H6-q77goA zq5&ZWVvkYm^L;=Bt>3KFO)sA_zlNsJcm&nN$qLQB z$%pr$R08`#Ov^2ZY1)~^)W+*aXLMySNy6|WQ|OC6jU=p2@5OTmsm;iMMTAFox$x-p zSa<-IH)?LgsB=rEE-?j(0_TckVL*^V6O+gBAU-DHO3vO;~TY z84!ZGq$Xv(3vb3tPuLogn5_jxo!jPEDt#$D!VolAI6_|6*VYB5CINFtYB_8ksqgpg zT}V4(dkbR&lp0^UdcX|{lkQ!2h!>EkoXj`*cX`8l_K?tYN(Vf)xG3R?wxCNz;`ys; z=yKx~5IfJT;$#1WIzun>(Y&B#K4$dC^;$Bi=L~_7mCaU#rn0OYsJ9k(o>^3sG>3^t z@h00R@${1gVSoMQm!mgf6Q6!b=V0>DKPmmkma@;!0w@2JiEZwn3E{>lSi?4=bUbf? zcG`7HG~QyTjJWu(=z$%4(uwxNW3W(Q0LsX141}}cJ2wmn>N2ij0v491s&XSXS_ryX zoBBG2sx4U2i9z6!8>{D5@|qA|i?U&ic=8LYlsPol8mOHE>f$Vu5Xq*_D&vDW(;*qx#EA zB-Y>bG)vCo7BZ~#79KV$L~7zpfZGYi2dCcK%b=*1Y9_iaOqZDIuA>Gb2LbGYh4Mne zhjG2_;#h}8)f}E?Jgt0T2eo-pH)Pw=2lESiDMML~jjTYxR+okmVnrvc6|oDPL&M%I zXG8$#z#z@1wq-PtpC#m{1|mGL60~~akWq8g^U%z2=p6h1w9xe2?nG`%znZaaiJ$%@ zW7eEya;;E7St-z1ySCs=(JOKY9&tPwDK=`rl}zVyT2d1iO4~W_OMWS+YvkP^UX;6&zQ(tl-+`{<9S(il&@^RA9L&a6rR25@(L%18H^PKGs1 zWQjJmjM`48W3Hkl_V!z6BX^CsjJAH159FOrR=v2k#zjYvBr=PA7n3T}#oN(aAdB1J z)8&0CFMUwll~8GTAwhZdw;^f=Tclv@_|iHo{@T*T)CgWWBY?T5T;XKnRSvC-IaY&- z0-K3ikK9hc;?js^W@MED%35k`F_O{F8*>eHJS@Y=h;8X!J0@;ezN#ei(V7x8=0Y2P zPC4gPL|f}FZ!hdJ5C|bYA<}+@CZ?9UzCw=^P#0(o_pK+(l|Oi7&2ctnP6ReVYH5?u zx`^pwFBcd_q>-E}_gL6iAl_YV;D5)8fk!1)rk455kgbHC^fgL>5nEgi`YO3vRq<9j6+>w20-%C-J@5+oI7t~sN^OUw68DbeB_0kSrbts z$kTUnY+ZK}Abd{Me_22PExs%uQfoyz>5@gzz~#-z-`}5q1gd_Ug6{ku2l!fS1gXEeN+h<93!G??Cp# z2@j;9e#{{cWGE#66h{Px`1K8tNI8P52R=~3jr7B00&X#6x6c2>c=I5 zB2?H?ed%lu&2^oh*aV-Bn{5Pv40XeLah@-k=L{>4SOjPp~e);C}b$(`UAPz8QORG%4XL8%KMUMVRk zv)tjhF>hok`$K#s;sKBTN0q;Orx7+Ky5rht!d&wDL3sdHbOM+AMM7V2b0w`t&GsmH zkP=J+5DsfW%AnvBEHg|@|HrGr^ZaL|09{?Dx_mV75o{P!fS6Bi0{8+NnmYk_3LD;o zME1L1>U1zk$oYxlwhN2+14%S$7>va<3j}VC{^8aF=@NIy#!B*+aSVQN9Srr$f{}v; z4A3YBZ>Wxwf-SCJNdsHEaP&jug554wZS5&9@I~Vj(=vZJP>XWx&E=F4ZFCUrx5Vyl zt@$t~X8d(LX@5<4rQQ-=3Dkx>NgUC&+Ecu=3DNaP7iOyrOORnzeVB|yioqXA^V~== zn=YdwE57kFVaD?(kx0C%;{kIP?`_~6M82=hUK{$w+^PA6uAe0d^@V3Rf!Z*)IqpC3 z1}#mlqd%c z_WW=WO_u_WJwjzZyrQcs%p4$kLC1qvj~@_%WuEg^I^h;n1V-`OX~2faZ(QRu7;sbc z=ME)IT(%(#)XLYY*ide*vJCbI^-u9+@)VvQpON5zsWjY@UwE+!kz_8%FjI!uix@M3 ztFompQ1{Gp9=G9Q18>(V1fRGQ<>?Q6EA#0k03kWk=+qlgsXgfm zK8OeCe@RYCBvuG9*A+tC#8Y_?$uY|*FWK-G+dPw0hlr%=#U^MNL{4fO}6cZ#Nq*;;eECFL~I zjY5W{Db2kXAS5N_7s*PW;dFnL$>L=gMJNnuKEhB!(vrZ266~>k*Q^_MDXokhDe8$D z!r3S`w5?__i3<_@?iSEQ5cA{)#*Tf)I-4w)khU>t+KR-}G6xz95*0La0R&GX@)%8+CYXA>xU$G=)GnV?J=!J0CyUFF*kp|S*?k?s- z;zJILGhA~^61te6ml@WQ85Tt!R_H6A#yLlP<8hBf9-2xuvXA{lT5qW}$v$0(!;tm%`vM3zxaWU?7x%%#$Ri=XKv z^buaONC8D^l|ke67{wr)Nm?XR#Z>sW>0LJGdYWA$nh60?#jO2JG|K_0bT$VXghQ1C6E}!U$Buu zkn_bf0DuElGFkMsDC3-315WreE9uc*O)(;ysugUo~@|IW*3X7HE(M|Co5z#Ahb z_0f|4=DrZ4p=Iz;CW-#yFTu(bz+3o@M`jW^s*iU@=zmO$0(i;5&LS@ln)5({S?uo& z=mp%e7_U6lC0;f4GoU&B&R}e*$LS)~lXhvW={FU@&$SF=ORb`_7IF01v`^hPKQR+B zxio5H;4n$>2Yf*_=_fdn{-B4bLBup5EnSfcl&BkMQ-6ZtkeE)v_QVLKi^R@`K6#p* zK#5*i0q=s8DZF{axh+HVc|_Yd7f1J6$A^MVwZNB2QJ zvugN?hpx1-`?-DxkCwRQeh9tVge4CWNJ~fGfcjYe84o}uV_t#!4|)db*F@Y3_Xnqr z0(1|~+grLmgM%f0c>O^wbd&yr+=k!^{s3pj54uP;Pdz#GF~``nCwoCm46K-ch!*=? z?<^$2ANiSsetrms9iYJ{$)HYuu&x7u+1Rb`ZhZb{pGh_BxRmy2fX5;ik~!tBIlWDI zh3{Gqy^pjtXsbUjq}(o~w4qDrQ@*Wb5ne6`I9F*&cm!4XZo?eok zS(2VzlAiO^+b}geGogNNz0 z+$c2V^!^aAa4#&4AP$A%LUDaI-BAQ+5=3*I}bb~lK>iokiiHj zb?8L`qT2p&bA%g58(pmOxGWXZva&*_lrNm*)vFJW`r}A7sYi{til(OAze13xuXG%i zp?W{L0ru%2$CLryUs^<;LHDscNK=s@j;WB&)m^ukSW0=CrREkWvu^4TPymzEPbM?P z3}8Okk4!FjLP!1t@qDYT?<1hU34alI7z{50iuu4bluD!wNEvbi`OE7HfV|l?M3}MJ z3`fKlvq}*sMi(y+cRFJnq?^*=4^4bG*6fW*eH%7a|8?gYXC~Q^G9a$Qb#HEog7YOqg z4wMiv15$_G4*Nhg9naq3xh&=;x@VWjNOO}MpI}Du4gO#z=!^sq&06{H(6{_FI?b1e zRF<%#hCEb;G!ZC7lP~L$Xee%x$}$h?@*0vALYRxYJZ+&XSSks)5vpLig*Ie{P)&&h zu=Ft$G~lWCRGO}_g+qfoL*gm>5VqOg0Bn_%;&mo?rP)D|0|#aJEqKY)QpUt+?5xU4me9q2}h2n!8$)@f8y?%cu=ghP=OA#uOs8r24^AiJa=V%Kj1| z>@&f>AZqldpRAAEDqhKyDNk zlHws*r0V1g8jt8KY*1gQUtdzaVe2<;`(y45xlID3M^QkMLm_bZ%5WJOiSq+AAYN`n zJedLW3W!XK3K%o2pKE-fZ zW-`KBl`Bi`Z)-P*L(Rh^o<2SWEpk^g=4ATEysRs%EQ(8TWVsgXSy2GW$<3SwitJ)U zHC+%IeUEbC4AUxVQ!{Ky`O5k;Oj?r3#yDPyk=QuePfG^c^+GqC73L2n_0LKJJNfNY zH&A7HM>YZzMaCE_PK3uzZ_S945!0PcIVlmUM|D(ED4qgQa;%IXsv7H3WRIMR6U$eqj>g|LtGIx7AX-vo@nd!4l1_1WA`Ltg*C z+E0U(8V!&@Q)a*w@2sVIn|;fM)`VknUw`Jq`<^1VIW&YK8my5+t45kG$_mJU!Ts28 zcQ@$nP}K#rTmWL_{iEvV)&LfnG(wVq`zp*~YL<5|wrx$~1g_Sfes14A-+qR{snv`K z@JYph^s>hGH31jc)cpQtgR1w3w*ZgFkGW}M?xCO{W9iPk<*jox!x)Ah9}}&3-ejmP zqK!^BXZC>EL`d=q5c}`!ZP9Wf2-y?QD*z);z3P0%kPyZt`505Y|NGcICc?XnUCc5D zQH%gb9n#laT+sj^nKs1PT#JT|KuEH1l}q?yj%64ss6-}=RsxxNEWtydOu7e4QUJ{S zFw)YlvAKhUtjxPlf(*qD7+AyZmHqh3kZC0(T)iGH%t9~E%=?AzJ2QaD`Q??Owf>6j zwI>tYqLe%ox+W!=U|c9(2fay59!A3!kyJ5vgw<4n5}WBDi9T52V{5l2QzE!x+|(&;@;4i79W6e}WMo3+9pQW5AJ`_+2 z?O~O{0gswMB&!c)fo;-YQ^CaoZ=+C>o`1*xTLJ56MkF$wP()S;_!J>B;_sV{J{!~s znk}U7Ay~Nv3_%D+oF&6toHCM3%46z3DP`J3a0fAz{c_cxCjD90I2&o%>KYdOylkp^rhKU_m#$L^#gu{;R5BHF>_@jKdt5A!4t_fUY`O>lg zL&rSy(ut#~6rZ#y5>b zF3Q9rxoF{dm1R=99BcPTE1^$UO$Wj)N}ch5iVH2en&I}sgbIE6AKq^RDQbSk%QC~7 z-(rBS)SV{uS4!3bebdRSbAe2l2oWp^jBvanTMfGwZld^tpDT+B;pGI6hPBk~qR(=2 zSRx>p(^zo-1iMp9c7VU$h}Vj*F%tc&A@nRGW>k^SBJ?}4Lhe@j&l|Athf-m|O7O^T z#9+*VQOQez-2U2*PYG+Lzh=~k2t^Bqr~FhrLaSjn#v%MIvwQA;HL?+^VJNLC*P;=F zzbJz=X#gMnESbhm&4PXk)HA>>+?ACW$X;%!OP;+Xs|ayWSav{Le$|yveonMvRMhz{_jg;!G~)dIiY;e7cTM zNPhg8uAzpnDEtmd1nH1W2at%(Bz)p8(XGwTEyj9sWcjCS11aaTxLX8Bo}E)HPr?W; z*@>cxkT5vxs4TD`+`{sT1o?sp4G-Fap-N_27&lU!c79U(^gsG91`j{`EkWy*18aI; z;SNLuu2(K3pMXo`TlT#e%Q#^X5)hs)}VZpHrK1cADH`!9&|7-)MXKo3Yu-1_Cbb07$1D_wTbvC`XaC|aY ziiCOB!`;j9e#ZLwJQ8@L5LmCFxM=LBnTQKcM7I%&rM16r3*SOwg*Ss84L*0Uxn~9B z6||Z9#mbEm{LSOf?J2wnX02$N^!E~1790{D?z9w*_#=2Ett)~|H=Q@l#}Qr)*h!N| z;4?4yc`#zN4Q}OOo#$&E1f+4I(LOXxV19#gI6i}##j$KWu|>UP1!mTk#;-}!6J@-v z1m4yF4+Iq6QiypGDnvFC?Jl0FM%oI zuVoSoh5`#d@yxMd{0VSECLS3CAyY|so@`_dakpD1*w>L<2oa71;Qe}nxB@oF!I`~W7VV7qLVv8mdY>UFG2{ zo_{lCi6!K~g|xh)bwg@Md#)17a}Ed>I%pj?GF3 zvaM34ef$JlqYMHILv0)1w(m?(I|N>dzco`rZ7k&_H~%eb@mef#k@`{w}&yFqC{KAG7_8+U*CZPBXSwM;j`Lvzyru_EQUZb<t}VGAmuStd!|jPWIbxVyCPp%L(ExOSE> zrfC*`da4k~AdGPO5ueLfshZ!X zn^|hgFzWheVGxDz&fr*LV;hcmr>=2^FF z9gPZ~0`el@2d!HI9O1?vpd)J=Z!N>?ZA8aoGecsjn*&^-AMRzOo3ukqR#bvJ8Q^fu z)dJPMycqwzm%Fe6bU@AW*h`4eH|R_;z}R2tU&S=?O6e6>MM(eUHD%aN+_1j0c?lqp zjpZB-=gI=U#-YuPMS|}5@?Uas%YuZe6FV#|${RaW%Is1QZ>+JWK(=Jv8kWzSFGGb| zB)(xt5h5@@5ic$Co^z#Tkfk4i_dYidzv#SpwsbVJv;&3ZS0xI1*XCF|Z_|bh}%RaUzKjSB@)C%xHSif6<+fQIj%p z@iVoUS}Y?R^XgcW2}-mHNRs34Yx0YkvH=YyQoi6)qi%Dip8?^9WNN{BaE~kvcPUNq8hOz7>Ow01)~4U*TI_;=1BhKgSv|-QHY_ zcw+t&i4pqG8x=$C1-a*I=9qysTP`s3?EAJX(P)^L__lt+GjWJk&_<)3i47a)L%zj2)EVfw0!QwMgoJ)loGDd3L(wAw( zhi_5teRTE~Y(|MF(lH)B_NbX2#^@U2O_S@ZIZx`uEMM(HlC^=Gbm%}#6YePiMN>Bq zh%{cS-cR#<&Rh0`ktKwlSQDljN^1g+|6-kprprcmP(^$`Hu{usMWv$3*}t|_5RK8&Dwe;EWQ)FAd$f>}DzohYcR zUs~OK8?5vzl54OsxzCYYgO?xNO+;k>vo2#LyvaB zVy4(K@BbYfD9)2lKHNy?0J*QoWdZ`=8BOhjAB3fAAk2EtZ7j}W)4KJT>*Xjw6lAd5 z?slr0A^zS-n~Ph$$g%H)Mj#vkdB_UP48+H1&E}DsKx`1YSIq zL~k0oOJNOhD$$WiivK(5v?vGuThPf^AMYlVDgW=J)S~eDZ$T+C;oeOqD$Hv0-!ttz zVfSB58)({?BZEfCdeV*<#K}SXOMiT!b#2@wP+vW$?8W%P{PR`^wElc}nvSHy#A;^v7uFgaIEjzAos@Nr7AXLZ=+ z?Lvt7f@eesNe~QNWBh(L>kVUOz012nyOW{QrQ9bL*A7`)X7R;--a+5dgqtCQTWQ9F zO;Ji5SuJGIp6j^SZqh2=AiA=+iWV=4h;#NHc*7dA=mQcSZyCA}YC8O0Y@#-5nSjx@ zaf1X3|9OlXd(4qnn0!B-DR1~Djs|v|7;v;;D5Ohgg8&VE{r^Ns$D)c2=qkAQG+4rd z${KG@C*8?YxZf}h6MVlY-;oBA>CifWA$fo)TA_zb&Ac^Vl**G9jz%oKHC7*U^vf&e zwDwv?dHbWRf^G4V}8z?zrWx zb1AU@Ks^PWYxdfKWz>YJEPIQyUENUFSzq) z?L{zr95!@27d6L>OO5043-T7Q@xQDxXJTIQ*$!PM*aIT!%Fr%RhywQ+VG9dvEbL_( zVzmuymUEf$O@uD05{A5XNG_g5ggmuUzi4T$%|aZk_h$>>deMJBq(Nr z=tXBW0z#Y*ZIHtR{EN%Nxi7*Sq}6=SJ%wCxTAfann%I7uxUfrZbIhq;`z<@C_LHG` zcLYhZyessH0;6E9{l)Ei)TVFhUV>$b^vEI|xs|8g!5c?Z;f*Z}S0;S)i?<}dxLnz+ z`o!pfh2`%eyU9+nnOSV{QK#s5(E^ohXpq3d5KGaN`8E;-iGMjX!i<*C457%^Ps6b$ zBRdpOJ?Vx|X?W}!MH669w7F2B}97hYcXU3iRMa^&5f(1 z{D8@w%QJpXicU4r!S3LUZePKPZu~Yeg0wbYf9PTPj=7xIqdmM|g=adO9Vv{tVa5i4 z=vtTL$A46Zon5pZe@Glff)Z|btQT@-TT(Ef^rMI2PIq`UyN={=qa=o0yX-nJ=nG#ae>!ujwcbgx|0a}`IW6kV-uc9R)BftwN(xnuiW?^K>*yL()E_2`s6R{`>da^>Dp4rM z5S{u*QPngiCW&C#+zZaNpI*I-zu;(UHz6HqB3KndlAM`Y91dnNgdl31I>ZAX!cSzB zEQytD$!Oky*1Vs|34|~w7*40(cI`nQB4Q*$nvq!v=xDLIDGd{h(Ggr!37T+3 zqgWR-FVAgbu~QSiSx>v1NE0O%QA>J=1vLy6=`9pc+n6*)BWfl+i?TG6UPxKUWQm9k zRG}{)U@+mtetRY<;(Q@en;iOy|54W>s0zs;crXi9f7{M5zHgRbq+?5fXSg|P+Q*eI z5HJZ0-%nt0oWRlvqLg4jGSI@0k7a6X1kw46eh?h{K`_2>j4hVQL^#%O5XCZt#4&(L z!R%rC&p0oL;+AWiRu>VB&X~o$gbMO>Hz|6J1mqhXG2^B=Knn6%hEe`yPN)6#3AV-Q zJVHM~o&xa;i8wN5$;x|Qh6tNn++TOtT{M|=myufHOZSYEkUKp>gK%$6msaAgWZ>a9 z#waLGLg-z0H&_KK03uUP=MqH=nQ$Q}8T+P6NK1>E$kJqK8HyhG#`_qS@bzp0jnGex@VFGyll1xVtQ9Q`&ljOTrJ?CCxgh^c{5ZbFwy z?nGuZm>=`{`ww$Gjz$_OFQ`S%0w6-2cXvQsj9vu6o8$g&u<8J{GvWJy6-)TLV=Ic_ z-C&~}X@pUD4lm_N%ZRpo`~X5*;+)9$p&Jj!cY?)Z@SR}E^m)6F|5<9={fVeNa2eJX zcIJd{ORyCoS3}U;vzEkHy^c%N?^4COMCJKvaY+$hD=sPGE5#*6e4VK3WIsPJqgp|V$+57dgM=Kr^PdO5Oua3&AJmT3NgiiCm`4cT z9-YkJ9i6w8|LbzNUm23W4R>W_={UR%^V^B<1hl`n2pJH(32k1Yv;veROT>_{nLLC` zmhjdcWzCM|)9SqpNwRG@6wGhvmG`msS0H`EH2(^uZ;(j@>EEk8y%8pt80k~*Ia@GQ zVSj2cx&nmt?p1%-=+5B(i&hdo z!4u+1gf_TLzQeLJOcg8Zw&zB}-x9V=qA_buW{Dq5^;D{Q(D?C( zf8ba8^U-ek^D$ivfOliM!}jxUiS_0HH(hprU&|$q@Cs;m0)qdZ!RzKw+a3Cy$|V!W z-TCbIBw$WPx82`U3A8)LpZ$a1lOF)NvR@r`z5y3UHyJ(|375)4fQw=65P(ZRbJ3uU z-Rp-*_j7yPaoOP!qKaleYGH%~C}I3H`k_Z2^{_2C0l{V+yms6l4Dc!$-rcz~FBgAc zEwZEpmNt`a1=UVX=pEsf!#nE;z59~jCs&AVDGcJnYXT8J6E;Qz8o18~mD(kX8DP)0*})A)t}3=_`wmq z&!0cUzZbyh#*+KPzy6#XAk5Xj|M>s@KmYqj#Gn2C<5_MuxjQa*ult)XlWyZ>@3{SP z+b(u~{PT|={x$z?emAC`Cgyj8;q{!lulpN*Q*!WQf{V;0eOdm+3RkgU){$PXDI>Q8<9yl@=C@Sgx9r+#G6mN9 zSFljl8w$?j!&UEs;z~wflrhz3^Z;%gCV3wduVfsI(c~B^{STQ&^#Q~q`~-MEJyCAt zq$>=-6pKJOzJ9oC4V$n!bP$ERzRFs}KF}Ide)915AJwk$nceZJ8MEJ>`kmSJ9|&V( zyl5CrlEZ4T(ltLY{YSRoDw(9WYMEKKbx_@K^-SVh_1IwlBPiYk*;47SaeKLSbX8g} zT~$ks(t5pAssw9?rRmAW^)Xbbw4-uXKypreOZrCoHl^i(~PE|=;@rNiAL zbgf!ya_=`w)Vo6zvi}{{N>B9-kY%%6x<&VpcU7-M%L%~4QW?DkUE1~X;b;d%%V?ld zx;iW)4HN;O;VuSi_XzZ_)sO1)!_(?UHC^quFRCZIGZm&v8jLHf^2d9xpOSDFoc2BCclcT-s`qkz9>azOG07tFO zr`qo3QMR#HuAOf6+mF?kt;$j5>bluDc|Pl3tnHN7GY5^m?pF0`-Z{B_y5cTx-CWi- z`kmWO?IcsU-+y^}z8W*Yi3~+Y5vp2aLjb6438+Y^DLTdfyKHF^HpPmiR zuGiE1+tbU!Rr5G^_HgjBJu9{gSNTEr=DC;a&T^T;Jb&HE>|S3FZo6C8n+&izJsF=J z_eb}+%RzRn)!9p(4s#d5-El8JU+ru>bT4M@hs)OH^IAK<)6Q%RjxsxgdVOu9obMlP zb+-;`&DGo7*0?wt&KcnR^zpQJu<_Wto3CE14pvV)TdUJ%C%19ZJ6}s*v`3e%^viXx zdv@G8Z)_i>%14v6!cDq-KiN5d*~-;|-JtMPJUPbiD+V~2758o)>c!o{xOvcec{%J( zpY}E%8W;1Y$!>AKc6@d{PH${Kc7pBR;Gl7^oxa@}?+?1O;^}GncG5mR*w0z`_?O^x(rMI3tEDZ9K+|^)oKFuB%&u&`9hiorfKUphYZq$0MUhN$B z^6mtst$E?LkX$|8*#vUK!o2xdVSx9mll#_lV}JXyxxRI_b2Odbo~C#92O9@3lMk7z+u3@vaow#K_p9yFX63#%slT);lm29@w|ag0 zxYG+xUYfZ;X39Z7$d9x4Yr*KW^_&S(yXl8s;U@dIdf(lC2=cYF!Yn8r?@fk5eRU_e zANKDnL8-ivT+Jpcg_p;JgF*A)Waqw+%p4neSYPinYR_kr;`Hj|Wbf#{RjHjn?r%Tt z9PAxnNuJ9MgHmNOU8}sTj|=CzFSH>fr48ZkRrqp0xKKrk(4v?(xlDd*dK=xjE|J zuRkv7IlTj@NGT^XKbwA-mB( zy>6x|`{k2Kp)otZJl$yx3#-M>Ak}>tCZ992otwi|9)*6Y{9)%C_k?j*B4?be&8yRG5N_3CAJ);&I+3?_Tyhr#?H*Pj;mr?tj@?)J93 zeZXBlzrNT{zLd{)*DoQyk|(|D@Sxp(s-2$YC##p6xx1rgXOg~8Z#TDF$A`uCO|qIU z6!tRt+sSd`toSeu_AVc`*DqV+#t8$=-rc8G>znuY)6`8N9qixr^Yb>?HN8E5IM^*` zisRN(b8wm73l3Vr>E!<9?jhaI_gc^Awaiw1n1TctZyly8)%#ML0iGW1U-!Vhm#YuW zM=*Eg;%tAAzu9Uv2kn>h)lvF1sBG@kF3+pglWJjau(#F9l(+VZm!<9Jy_446cziTC z4Q_W{2DujoSa|MsI`xOi{aJc8+kKdonz={N`0Vs*E4wyZ>kRuBkB#x|VYN0mcE8*tPx^D=McZ*q@=JteCq$AGTiRx#2@zvHQQ-)x5c(;4AQ3; zr)P(?+tXhE_CD3UDo;`eB}~RnfAX~XjH?HFYdbGTxk2Ft!*re=HHVY#>}6+joPXSE z9X+LsgX;F-A%wk1?7hz8$wm1t)!VF{zVrq+x$JdemLFVfHMd&%wbhHe@nkE9GZN*; zRO@(e?{KuI&{ z@H8&$&5I|UTzy^-cCxpb^I~ScTAw_$PcI%agBwWH-C!s4vNK7|MunTz?&E$tI}7d^ zVCUf^*X)d+PR6zB_U`CBnLXXUxp^p`PKv|YSqpOSZp0#9Nlh= z&quRHVRDl_%iLU!_gkr*-KOwiel@*4y(_GC+dGx#PVP8Wd8u_L`PutGB_hvf6qWKb>_l)M&Hue72Wm45#helk8*dWUsb$c%RM9 zCyo2Nht=)TW+8WZd2n!$yX~I!p69dlL2A1;zaQS!?|aju`|_MS6?+0K6VvcA^OuRd(8=5H>qHf~2JrGsiKIeF|e!26@_@p#g& z1jG7GVV;{bOPSO8=D2YDlpbB4>`o?|t-(oUudrRXnVn?s?=pi)VeMdVZ=Ne8AD?e> z+WGavAQ6%)cka9uRqy%+|A_Lt0%qP^yn~ueP5jHZFSRyowKA!o8n_9 z(-~z()6DK1%6o8~n>^Q=dm!OKuQxc&)gNZN$(Q5N+V=5rc5kE6*lFbU_8)fo&v(~1 z!*M=eK3mUbwqH(yt^n+J&rjCYviG;=!S+qCa{@(tvU68xoEOV4&DKTp^75?n*ge0k z4oB(nu-M(mHTRDyd$sMYdU1GpKj;MQ^nLpUym++AT|OL7ij&!-d{k?mm9u*{wa)p; z=^$Ucub!1#`SE6by17^DA02i#4=-xR+u1_Dd%AP;{IZw37)+b_t#;$F-8j2{eyR6_ zZEhcKy3_pgeRgmXoK;>nYuAUx?Fs}%_bAwYIjgN*>|M4e$0x1a-pS*|%g%1^@6y@N@QNW9k^KCIoZPBW_yncLZ{-8i4_77Eq;ae5nW zlfBATHNRIaG@qxX=ab2K_hI{fI0&9Ax$|VXnSR*Y$5ij6xy#dPakkkx&Qy!@?TfYh z)2-ZU>v%udecY)|PWQ8GCmY+dd@olnjPsrQjbZ-!BE2U-6t-@jTs(GEM?VcVE?=}mQU~70+IT?2jQ`@P#=2`x1|KQ|e)Vj~jvODwo z_T5(NVPoT{o||tR7Y_E0vz@)^>2cMJ*|6-JF z6gRfY!9(_>RvYa-Zai#{!0#9Lk$(zX!QSdoaPXKLF~HUHgXibj-A=Q0xxaT(m=BuC z^7icX@OI;Vn7ldc7W&!y;y87D(m8+xo=i?!-M<@kFONF&^ubQ=x_PwyR6h)!3#n=^IM}_of8Gp+wMWdV z!B(?Zn0Hdab9;We^H?Yiw{8LkSlYhm1+#~v-qZYa5)8M8!C)iUIY0<%rhc$`d~&z_ z*lM44x4MT&tBubKPY0_P`!MP1H!WC!FTqn~b+#Q0@VCGKpV~N4vc8eUL~Zpa^BrK& zBAC0Gpw%7*xxFKFc{V>yZ$IuHyrc`M{LT2`w%N+{lC86Pr;>U(&y5f6SH~H%G&{>5 zKBZ4CAGS7%jibRyca*)k&g2U(*X8j%w-xNJJ{6L^Z1?8sI_TyxNpHgk!zjGYy_bbPb2e;>gZZ?^&A040Ho(+%AOR4R7v(Rj| zPi}g}&HJ_E{^s4`xN~3aboYg^w{IWrg5lQv>15o6lQnlg+ghtPdgIm85f*{nv;FQ) zW0*c2Y!{yL!P9zrSWDeM-KSq#d)s%#+-m!5(mWibD!J>z{W)V;yS{ICChNWQ=}o0` znAv)$Z%v*zo;yeN^^N=EqsIC6>EYVOWBLKTem;j1nLo}hQ^%*p&D440EZIAqZPp&Q z_SW1TuZ1eOb7~Zxvk4IPlykO;tJ%;9B ze3a@PuGZ$Y_Ccp~P#TVQ@3BNVx_ihz>@|)K*KRkn?dIu5_oUM;B%9YFv72`jn40P8 z!_Df=Xn**;GajbKt^3MdG1Ey6k4CH8h5wJeH*Ibt$JItZPe;^$uw7nDwxmocQ<>gn z$=WwtvKH^!_g${C>%{r*_W?+z($&>7r_Vd@jT>>NC#KtgNDv@F5ClPHKb_RdSM%?! z`t|(#trdAAHCO-2__CEZJ>RXzIwp&(byn}IT%kLBOMSoY=jv8@;qkxgiSPZz$HX^D zWNtzpYn8jl*0M5M%<-1K(FzuC>a+UPn8p_V^2CgK%4MFnOfVI#giLGMiuvGG>Wg_` z{ALb{cTu~q51NftshReVA|+pXQJdSzd{1xpJh!P_YcS< z0Y6_dQS@#%H8bBjhL9T=ITUTnIkU$t(of**~3_#@s*jhnM_YB;HV^oG;4{g!`kl-r$; zPRy5T2CC!2&uCk!%{=>|x4uW)g#@B!y;URb8GP6JFWI>c0AZH}jY`m7n?#9+Y}|Znv|&!h1P@31@dc?)B0C%55 z742{Po zl-DQy#=xvEYUAegZW^wy?E6A`7GjZWv07{f^{S_8KYv)Q%G-F^xDDB%_|HoG=OBoo zuh;dlUB6G>=JMvEndtspt!~2F4>)mk!vmufsH_tHPH~|dOz`dd+|xJ9nOSUZHKxN! z{H79!H&^ez?=^inY}FfOvpZ;9)n_B4WDNtAfw}0^wYg_iGVMjnjz;Ub_Rsel-F(-@ zOnLkHJ#js}i%h$o{JnnvW)vE+3cT}A4o4qra&(xPw~U2n=Bai*R{n8uWEkDI>$hAf z?JvyqVJS9Z4l_~sEdKAP@YA-+?RWEjwi?XhBmHessYfF3%i3MHTbjlO{k!z{AVM(x ziE%gZB`~`hlX1p+pY_b~s9x;&%R=OKrZKp$XH8EcwCcb6f*+W*S}WFy-@cbCSJANj zqcy-jcVYE%rGYhR*I>ttO8q@$#*9XF5oq^U>6@$OO))(c&QdRz9!}>Ui1n1e8>Rk2 zFZ|3H_kR3)YIz1`0J#kHPBYw|Mc$LSa;|(|x$BK;iRle?rd8t>X3FEsR1pWgYm3+y zY(}ooxye>nmA6?bz09-_2T7*~%gX%LvdZ^8V`=I2gi-eAgW969=r!6uS6V8ZO5|_N zawVTD*)u&9^&lcB7O8@#*;=KvzOVB$<*Buow+KR6dbK*Q+(je3iZ;0KFQTDDSxNGIqPt@-kuk3ykYoLeicu1DSjcdOOh zey?LaEBi;?L9u$fn)O$yLg_Z17v?JvnGCA&(M@Oc-TKH3envg_ca>3PnKSO|H?7D} z3+wG^rJ*kurFdvC7>w^e(((If{C)ObpY+pqtbFVHSy-)-)_a==9GN_t+ux|>=*d}9;lu3c&6v0k_I=6F#bv?}d+ zvB(7LtxU68o@%}8#Av0j`d9C*zG;mE!C85kOHZ^3ocZCK`Ie9PsTZ?sSBkk5LI>shem*;iiCutRYvpeeKeYE*Wk@|X$R+AyZM7=D8LOM#@U4|wO|G9=fX;jI~5mM1igm|^)J#46W6 z+GXD7(KaUFXAXbG5ek@ef0dn*l;<_)rWV5_*_fq z<=d-Z7mLEE-|zSO#dr*B%is>tx^84XpQo?NVLcpvFB=_C9SZ|<=xKDag|Y9pkeiH3 zm0B*PHHyh<_jWPPXyN>QBdA?f%Efvy8;K*9v-JIF`F;)!pH_IAbnN6^!grsdQ;Uz9 zFVkRxcb#MvQI%z@_3DuB%;Z?n3+>KVVM*73|jxga}E0oCFtA?HnYT``F)SLc~*rYrf*Aay&;xs+zFIVaX zBk9YQK5S1dQqL91Af6tT{f%!9T-IbPupPBmmvj1_{oX?E@)DvGd8|BGl zRQ*^OKYj1L6rzWEwSuREZq0fwCDbOF%T#K&tN8tUA(czt+do3tc{ly`BM``^=Q+(& zS%nJ5kD(T%l^2k7_m&CG+m_b7XJC-#v0HVfr#g>Fe#RbxwN$~C-dD z3Yk{^=kh+@n+ES9llof@0m8cuJcK}QF|`7fTxb@w{I}I+&WK%QhXF0-sf<%RQ)YJH zI&eKM-@I2R@gMWsn{Zdl=jPo)Az{=z=k?f4(Uw@a%wOn0)M`GPSOXT`Y==wXd>ektMl<9_E z%4Uy~ljVx?ev{F2AiVv43wd0YU(-TCe@OS6mZl*?AZo=Tc36+W?Td*Nq|a5?qb12k zr_DD?YvEw@d?NNq&{+$d3ytGBdYr?TMycSt6203K8Y3#TZZkA29ULE zMMMG=SpH4@Kecg-9MC=`7e+?)^Jp)*9=mw z|6)u8nO}ZilTd@^8WdN$o>bNZva+X(57!UWb(E)9Y|lSq)elG!{abl_JYkRN@vQ0O zoL-1-og!x$lUU)_ETakW4+f74{7x-G|5`16sruLSfArduPbr=HaR8~phDxLqTyUws zCbFD%RzI-)4%4S%{wkwVQ2Jc-uSqt0$iHp3&V8z<6ynz^zh4^Ahbo!(e?L<4q3ORd zT6`Y>=@^UUd50{(?~|1`R?|*o2<` zM@j!3=H&YS@<_p)1pYHp|BjLRANT|Rd&AGU`~m-eM(W=%QvceC{?qFIt8u3l%(eLb zlUoE(iUS5^`w%ZK7bmRx139>pUyp47YhcDTTOyg>P&2$G`6Zb%#joAW^J6 zp>GA?ve$3ufQk4&C-djqMBw^3QD2t(%YI|j&g1P=B%i@;jMZ`Zkrm*tN~{?m*Zp%T z_jT64B=xD#pQ#}>+ifq;HHQg__;bl@{hjaF_J6kjhdTkxW%T9ok8|6L+jLd{n^J{Y zlNWQI%Jt5JRL%}yzb(r3T$;Ep_crOT&Li-;F;3)ms?v;K6LutWG47(Lx)ZtAt2TcX z#`U9er9aP9VAT(!{yBY5=wCVF=knW3|FWF;*ww!*#$T8GeJO$c%&^l1zZFvTK=DU? z)$GObjM?mWH@iNQ{L}~kLp_jnXyP1qsTu0-^QgFFxFMRyrEC1a47&@hhf@%t{$JCf z$kDmDgC{F7<}WKn=zX?2E?a&c>NV-V+5vwq@i(`^>&ndelDnI`pwhz&?owtK`ZxUl zLIYoHYoF6wZ?ZDO|GFC896m4H=5gbvC~Gq6U)O9x+0XH+A^#(*GVWhjrFXn>dG^=Z z3jMDMeDL>Hf2}XE|GGMVnEcn;0{NGfe?P^XLBJpXo1L~(U#PHa#O1vHRX_fcKVpCj z|3?vy|E3~n{$JGi|6{692l=}BtWS9L-y$FUx z^`NZ&f2J0{TaDM#pDvBZkNxeqO{y1=l5ewd}F+a^ZO$|0hou z;4I+x9xr~tmLc%@_B@cs*dw&wn(c)QjN&zqjZwd`sN)k3a0W3%p9)Dk_j`T?77sSy ztq7mD2!#fBZ88{BLXUKaKpYuKZ7T{inPBRuBBG!vE2(|8&>i>Vdyi_&?h9 zZ|kl<*3V7hsQhf}2Og99^3Pth`ttCX?_!;v`Y3R);Zu+PZ1AU_7*)+?&d1UcB9wu^hC*pU(`y9v4Yi-aVH?k$1wx=IVGBKMaIZ*&*VIkh2++8wGU(qB{)d+F z`6bX?3*+}vvkGQTMCU1#=otB>E__GIhi^T8`heO7e}o%PgT5@<%RjufrUyg84R6Q_ znK~$&8lu2x(GCU8&_;9oG5n+R2lAD?LHruMsq03UpVoqkC=K^%m@a zkm)x!6iPD!UO#jz=rt`n2(6Sb6j39&h#OJD^ip0K6vTmpmK6#C*1bUpWa8fhb6*RY z6pBY(ph939#UM7i#lqwWQN9<5_`QayJ21BkRm5Ttyc| z{UJZp5sU=_RKXwAZOLdb=)kgqiSBe4u`pPcSJyEXL_vVTfEBdV*a(zivCgAN2xDb= z&5%Dxf}npb7R=Dmm~4bP$igUu3}ReEl^_(}&U03iQczO$)<7p9i6bK~_~w!k=0Z zMZkz=>+63_}+t|G8uMi9-|wwRs*{=~gNL4Bcd)UASq8g<3Kf@L3p4}~Gd4J;_=erOg^ z5Q0D{OsJhuHG$GJuNj1KVaws5EGQjS@B$$RWK+L=4LUD)*3}c0uUBN z1qBD>He?Mdp?aB{6{P~Cp*GYJM2IMCNze~zd)9G?ON<2@;lNVAWJGhLby(tB4{> z=Sj0a^5TA124nh)usTd5-yEE^8k4dI;|7bVP?`zX3<`&dulvaaNcfYAi6SOE8&(lP0jqH^ zNV7&Lu>xIuDirf6=7Z`+7YcJSXwi}b<_)aEFvuY`*mAHG%!IM_xl3Sp(c6xN`$bJr zLrzBY7%U-mj;V#jWF&!!R8W{#6CDD*gQf_53}IzrtzeMa1_rt7pGsJ8Jp$-@cK7hR zfUzK95s_5{3LY-GuaX3GE8xfMAQ+7(kOjm@Vl)&AlTC6S!r)LJ3D}U!HdhfSXrtzb zG3B0BD5Z^9`b=8fm8xO7Lw^*^RNw^h`mc&$<%VfoYomfiE3yg|aT{1ulya;iV4~_+ zPq0r7D_F8myeX8Da7{wUqFQlDtcDX3i(wAw7(;X`{5L#R%){)UU}h{D0eD6*5HLO# zW(>nNJR$`X^$g85)xL-3+#4O(NM4)CDR4Umnz zQg~&$O(qsikdv=qCW=ZV#z zuw>nD)0RxCpBy*kMoCaf!ZpNTWA0OLux!|(VnzCl2?a?*WshlCH+dr@J5<50K36C; zEKnwdDpxW@mpB7!-gpq2q!XJZc)2x%}j39dSjAUw5=eECtz+E z{l#jnieT3d;|H5=!o|@n0V;uI4Jz?TU{Pw#Em_jFdD1Lc-oSdLWGa44%Jq6mMKpMH zZW01^2`q|y5?G)dfkQS{ZL&pDnhzzAn8>jE@?66)J_In<`3~Y!3!gGVF+HY#7c-$UadrUMRv6aQ^<%5iiBV)R5--}*WnZgCBrEMW3Zs6BAf!)M1TWq zJK+?dsE3?z3Q59INEuF%vMaA!_FxD>FNM-91Tx_fkjde2iiF+Ub%}DqDd=$%-i$NS zzbFG*5jtywC`I$u%Z|XfO_IV$djc>3kHA?`0Q-4O7Z!>;79;I8S~j@hbxM&?@Y*KH zB5oTjQH~7;9N-mK8dw`z`HKy<$uU}+WjM^3vozg|07Xg!=(fND^GRB+;#f}<@N-l{ z+Fu*94lA9Ko~6as5lWy?8j2t^3|L94V3)K4rK}@Qa)pu+2v8xaj)9d8E0`M=yeX6v z&oRM5Hr0l#z#ZloU=#_$YNBaGQ?V-Ba3~P7anwe3v4WWf%{iB53GGm}Q9w$cP@dIH zN9NZr{`VRsyk~+ja>}Q>~g;y&~d*dMmg5#WNeY)e$ztccw~fv zZFW!uo4h6oKW_~?uHYIa-0w9Bb|wiFjW8%V=Y4>3NF`^=X=Tn>80CIb0Wtx~wYnQWa zBbLZ}JtaRr@gkjP#t`_){dQod&(}qy`|VJW?l)l3hU0!K-aZZXXFWv63;h%kNGxL_ zK#jE$kIhg}(pjo?4GIZEpcY--Z?j{qV3wShCsz^L^HNw!toDe}Gpt(SDguQdafrK9 zP;h!zv>`z%FS$?!B$KN8FJhnq#Dmj9HeR*LvN1-*c1ctUz^U~{iKbx5r;QD?LgBJL zc6q!Wb9h+6su8Xtia-xI$V}1`31v%ED+*@m1S1M1Id>?07DPzbfqWPPbULdNOGhS8 zA?R1~15k#yc5B$ttu;zcc~oHnLX{N#wPI;lW`D6F5`_?LkoE;Mqa_MP3oa*YDquKm ze*A&u92V41J7NMtaAX8poN!`&L70(#VK|6qRroN+!63k^VS}yeA|h@D5E&qt2rHP$ z8+1b9pb(ISIe-&PSU7?bRBX!{RKh)LKv(B@x#$8G4ozX7s!CDQCdc1Y7b@7*%L=6i zLXqHsBMPDs20wAa7;aT??^>>v1ZuJ6UdG@l6Gku{V=I{HVh@TfgF>l+a+9FpRjtS> zV#L?1xRg$r5iN+NnEVWAI-S#z%N;~l;}}qfWep(mgranmZPEa{QJ*Ucf>f8b0w{>X zTYRpS$YEcKKXnXi2m{FEkX21iJ=_`t?hzk0Q;Uc*(_tIICXKa(Ar7H}2yrSD!L+2q z`JxEZ8srl+SwR%gE$j=q0HUj?py4450RvBP09rsbaQIIlTZ}3e3UO{l$qO8Mhq0&l zIp7e~3PpmnA#{3A!b}B|m%^d0BD4_&EJ@Hz1p~4bt^%{;aKilqgb-F9Mgqpp6wGq$ zi!ui!?1;NYi4Flwn_W~9T?&{YlM0s2YKTNA6y-)>&LWhI=OD>JgzKJ@Wn!Cnkv~8mZozmC?(FU0~iSj63=w9 zi>-)L07p5nUAn4|vtfp16I?@}Bp=kMECdX;MBosxPJ@ZfC(el&#yN)rOCli(h`5T- zIfI*ogh^OggD`Gk(GH_%?~1(Ik7L^=MLDNr>P9=$KL&37yAdSDPh#X1LU#Q|5S=12wGCJpk-h)2UZFuHO4DGDQ z>!pKH5)}ReofQ!rfWxR@?lsJ3^o*-S2zn3Lp}??gL)Ksv1{1IGu*f)EHerKEWETnn zZwEz3!MvuBouLNSuq_YYBu0nv3i4oK%7Fsl0Mb-YLo}jb7b^LS)cr?+ND-m9ja&UQpk^RAvVUfZn@{{~@zKIF!^cs8~2n|^Fs(>+6 zPQN=CIWmHR8caSarvwN&xNA-nMsng(MPP)6;zSLHakMzW&Wnh(LLo?N(jht>x?$FW zKN=J|KMcV{D41JA%b=l3P?7-#Sk;%HY=O&*0@OF8^P;xwRYhKaR9d#LewPf(%8J=F zb;w00mK4DGB$Y&Ah;(Wd72(u4hGgBWvNV)l0u!h#4V2$T#2X4H>MMBNFwGb)LKd1< zMo9sqK<I&nZ~SMqDVA!?+^xiy){Xh7Bh!2;S%vw-SRU5ilPnf|oSl4hFGTvM^8@ z#4t%5_9t*MWFvn=!NiO_EK(?fDV_&dl5k*dL{{M%z zM;JR(&i#OTFw9gC|Hs;e>36rVqK4uWhrP7Rb0h&w(EtS# z4WK?bPk<@z=m@)p9bpy9C9FazVR8OxVa_;`;Cz$}h)Y%^63|9Qp*WF1Oee}Ga6rsC zEUwHbMvMx$q^0Boff54)*d&^2Yyl%-&w(Ws#04A_wL=LXYjGWTEv`U8H`T%^D*+=` zJ-|eiw3odE*{*_RyTqD8Df!$a*x?Y3xaIZJ>7wwB(PtVRuOr-GlH&?EM5f4@SXdls zjg&A`!QNUrEMo3qxDg*B5}aR#fx|qeVc=G%3aJ^TDbUdb*>}LSKq#t8aTUx}Fp1EM z3Z>>8!V@^o2L<;mMR_@Qp`4V703U@?Pia4Zb16oVZNtFvG=edK#{m=OMrqgtDHI*n z1Yy%b2uZ9kB5N3CNF)v_6#T0It^a^&q%iEfgyCd{oJt9@MDRAzPfh{J7#)96Tu(77 zc^5JfRdU+oBw&HCVxtd%V#QEw;2aRT00@aDWWA({13`(j0)b>5RAOpDW?6xzj$8`n zQDF=mYJ(g=Q6XreUx_?oWkeu=L}^ijb{?!Sl)+60RCM6F9ySE*q#l#9a2wDMOfjbj z9Y~=H=}VB74+SH)_26bcg+TX`PDHA+lWz1rYLz(@Etj1j)BG=4IsPKkl)66l?0gt#!K!t*&Rh|P+%0$kb2Br z%rH43O0#4U=%-Gh2=qEr5QdAoSgNnGV~TN6Kr+dE%RY3Y(A%^dCVkU|J(VghMhe5g zFtZL5ODZiP@G!G`Eb8caxQGS$!sd1o! zoFuU>Vp7VKLjqn0!7lF{RTza4Qm#0i%ZuHG8%4*P&_71eQN4w8c)-F3T*Jyslo;v< z_RazG0V!0By>r0S2!3Z+a!;%%6b*pn4sMR)ov%^CI|oej%5l9xm@*m_%!FZY$ahlS zIq`ilSUHH=?f~=345Vd-y-ABG{5DiXEA7(RfWJ zyNUxriIN5dTd?&)Pe+V6^W}-HGPHpT$Q?ENeSjeo6>%s?*je~x5pb;*{xwD{{E{e2 zh=m_8wX0y3lQ~lu#W-L|K?nj^MF-ZRF(aZENFqP!JtjFtLAVbb6r2wUicKsDFXYCSOBU>3J%PTa1{q->*Sz=DwCl6Ho6C(T9L49h4^rlkeoXd+>)S% z7-gIY>Tq7%dliLJJ185Q4BG!l8#Sr4rStbI6PO~(83Z*tu5EgD8^pTgQb+c+8 zMknhO;*kZAbik2VRb9bu!DJCkbKZwZ3Z#qd3(7VW%(5{P3ghsoC@7xSjqupf*_26} zDrX<&VAkHc3&k@|9cYn2G$RStMc7q20fh3qO&gBIEbJ(qNxO!fNvlw<&51&(%?V(G z4jkle1lvJu2_2BTK?YHs5@bAJPw3E$!csU$W_Z0jQJA&7P9bGsPz2MT2aqigPN!+P za9MI-D0-$)bbd{@lh)!o@LF7flJ0o_7JdVC{C79yCIe7R>>gUYc}7`bC0kZq5c_1wUEe}G=Z zE7}yF#8}a)>+mEu3=aHh!$3rJms19_Kqwg|;0=moleY*6_(T7oL2AQ52nEvLbX-Q3 zj`j;KSZx?wDBdwJ43?2|MjHkO5vc&IHVlNa!61z)HVniZU+!|o4E`M_TDXQ4gFzPq zR1qBU;z|?|PhOUjh!mN#-zDCIbB)`EmfON*?j1_T1hhj8k)$jqPOEG{Q z0uolXkIz`C$lBC9C~4~HJe6jtwBvky%5%esx$$Ya@F6%1M~C!uB@0#9)H|?a>K%+* zT3N|q7H5Oxg*d|CNE&lMf-Ei_m%2+p2oZsh;yUnJT!F&OlI|#FIb*BluZ=@7djpH zIwLIMwNs<3A~-vwcp^Ystix>ERU3{=NL*mX(Ey7Al5g5+k{T$cvDnCK)ecIECcJzH zi_WIAN|(SiJxKp)DU;-YLaYUX(ISSqPP%T9m8P|kmUszM9{^>ND!7UuDvb!@nuLV8 z6wb|wD|K7|yB1Xddjh1(Q++-=&=u_Nd09jm zA)-Jxqm^<|8x&HMFf)o-0Ow4hh$~#!BABD3s=F}W+^MJ{HXJg&Appl6FA?yTN~Sji z;5gF_a>%UG8$O{#dV{Jc#!jU-Ao&3Kq~hwJOm6^HWV8rsutbRGAXfk_Lqa4s1VkfT z175bn2e%3YiAs6hoKhj&a1zdda4NTfU?r@~Z2(Gihsz+cX+y=mY zysUs$FiB`kFlxB3$01GmTm!m}$Ch~&xeYFq&?@95;Ql0wMVAI?r$qe5Y49>ic$ZUdR{0IUGLm_Z2vc(K5NSuE%~T{%-la1_sX z@?dHa$A?%FcC{i=U_|75<5>U%OV@mU76pw!M5cokCmJk5lq+lsC(##zcJ#|32P9Q-McLllFmniVdDQVPcL;wScyhkXh z8VU)^P9ip(BE%-mH!M8xc||8d62Q0xE3!4HlL!SfVIWI}$KF9<)uh=WvK~-`!|DLZ zt&|`)OE&~C=hg)%Vgt~rFJW#%)*zJXW!WmDpq_lq9nBC?bRk$3Tu`$LmQ={4Qz&Qb zTqNYc@mQjYRAPj7*NVV8O#P0&b#z#G+iM*b@FyLXC`X4u0z(gxqzEu ziArJVkQ-g3KxUpc94`IEQ94uz&5-&^z{R@2fK{oyqPC-%g1!P}=MV=9MV&<#ctAnu zF7*zC0PN_lLb-HzjS{*CnC_e@)dWcQN?f`N3=WAEhLS97Na^VA8g_J7qErWy?kbd0 zJW141Oxdi0SzN)GLOH|cA|c1@v+g3Hfkpu~)q-3!x&i|wF%X;P2`n+_dyQ`I0i>`z zdJZ=-U@DPqAguz!#0^l~FRmhV^%GUF>4vSr?-E|$o_A2VY7H~5NT{`5wIX3|1*Qtx zf+0p}(i)5{HkW7xVPz}>3YMa96;VXVOPwuC0c9AJ;RBd9@qhzCByEzo@Pr&#Hcama zxQmERloUSoDJlpvfpc!*NnkA!&wDr+oRU&Y&?ZdzwLH)z_>v0dmZ4AZDHVz?$A^R# zOA-#ujmRog#I0Yl7L-NUM!-bXQ64Zt4J(+b2;LNmc!e-)3Idd?oUGuI79CBiAsV8) zK=5jiUM1r4Ym{NqG6dK{d=o{28im9ZFA|od4O;44MJQVUup|Ly1k9}{ZU}`f3h6mf zWfItP;8CP?D-z}^k`bqfX2A>E#_U!wMRJ6PyvDFjIVIp3^D{!A$hSQu%zY;Wk{F(4j3KK6zZw$52S79j zQx$JekqsfwUaX-6a~Hs$5{@^QAc3)MLJi#dWBK{*28!Q_40)1_X`&w9=-?t`iODU) z4ugKiav&jYfVLGd7fu1#5iI|J@p=$-v4qj0f#Y^rg^SQW6myD;kZS^%Zn+aouY{0T zbp4#Gh~5E8oP&}aw1OzNOG)l>yXZLt=)t-OrC;#Ug{=vhMghCM2Zf?705Jj*l&Is3 z@-K=2#)PucfjhR&7=3;@h85&9icZGKmOIKzX%}ntW)U${T&}dt86)jBp;;=2%+0PW zg02=mJzxtqk@}6_4iRlAklTP)<8rb%Qvi&E0*}9fvB5C#bcg8q&w@x3q$Eaw+CYwg zTVlBg@??{Bu_y#M9gWWC)&?Jm5tL4?764`t8jY>CLLr_B_m)>yhk}H8rIl3}C3)s{ zMJ-4!)>d#!??E`KAUnpTER-!o?z7S-B+doIu26VN68_Ztq6kKmd@Uk?XpEyOXo5D~ z3T8&3a9HUTiaMJfW&;6s2!82O)DX&r(|4*ys!tnG>gqL0Y(N3yLML%AmTWbWr^K078zS>X4v3Y}JaaLMSWfiNzczj%*ZF=Kz+R1yQGcl8u3snDUKLh%v1h(AaY z&{Y9D64NO>P^7N32dA!9DCGg6A)*Qm7rR5*u!3d7#G67P%qJvtkzk2kK9DLx`z*QB z$H6nbX-2&GDVhP8q8rZCQe7>VXKEOu!_A8ITB#Cb(#btluv9Hn5R(rFJSN z-#jp)OBJ;4bA^$k0ye3-Giss%3A&h&7}>pG%RSQs>&`?2NXN&{ECNjDNeY%!X@ON! z5hZ9`-4rD3%rjX;amtK*)(?IU*z-`WC>X6MMifdhsz@lMjW=`=Z)V zu#}J3P$-9UCg4EpK9nO!fezRul!AlA;!*xMA$WD-qj>~lL6)C;qBB)`&sV|RGFZh# zQYb2d2LTASa4`U9P7(%5F{fP^c*1llB`MI9p$lHB5eai6pvFc|mXLgdH1-XAyi8)i zd!tJcvI0qlK2|HUDg_iTGT8UvkM;B+n9@SkWML|pQAiU}C@Mm-x=Bb_%^y{SdQh%Y z4oWUE1QS*2F^XamObshoHcY%Jl;Rz*yo&7%9Jk_rfEF%Qj>Mp$^JBqbl@r4l#o9qP!Y@%tJb3ltF;AC2E0vF`|K_ z0g6E?6u~y^At?B<2GO-eOS(TFh7IE=;%vK!bF^JC;>qt_^Yg9=lf&Y^?I!9uAu3Sk(K*5t_4fCdVV{poDorElLPclav~v!~_M) zcHJ8<)%VV%RbwMtkyS{$Py|~=ZWd?NV%@|sA2CZ)gU!5fZ%EM)G(ocrGYyO!?cF7c z`joPrK@+e43Pof1v!W3Sx`;7{(MG58#$H-6N1a_(O(~K@NnUws$d3Gsf}29>2Xjjy zW0+UEwC{|TgqeLRD=Ny%S&39FoVsCCfh$40F~gmCg@U_9RY8z^ zM}*03m`%hnG&GZJf>VSxu&^Q+dO^a0xfQM=QF0%`GDCjhPN>}qSOYJlfs7$A zKrR}r6x)wc=XMF&eyOaEgf0Lo3pbNm$Av zM+=mx7kM+z;$e=9j&-9DHg-zkq>SI>MlIR14!rJs2PK9FE;vzeMo%^(VK*yoEpXJ2 zbp_lBO$|`Ao_dcLYO=HrMi>@=^!mOsB=j@gxKuDVhfD@U!WBx_u^1t20ix12Ik4jm z$RZHi@dgx1t>u7;D&!Pyuxwbt)Uf1Dp(N`7g%^yU#nHLr1PhFkR&)Zf%O^MM11lGb zPn!tl2N~sQl&Z`_0rZb&a5lj?dGw8U=X+y%Y zqnQm=L~*VtC|F8@DsqsqgW&nDPKa>EfSoI>np%WNYbmmgID|%q5r1ICV>P8a;w&Ig zB2gMRRiraYEWdPQKrp|sDq-0KK5X%+2tE5wRoIzD z6~w{_W|CY5f>3k@%u&J}2_)<}B?al|OcETXmOw6#0TT01L>wsAMC-G|m4w$@VY~^z zMPRr1AOqoMCgIou(TD;iQ}h7`h2q{8u^K;o7LuH90w^a)Nlrmgd9Fo8D06~fI@sdQ zqUC*kv_&XResC3`M=Vf;kGAM{hSx`1E)?fOFf2A@xCjQzuSmkm(R4+{*J*fr>K`aDNaf#(j6uuViJ z@l+q4SOVLaI}VDh247KE7%WTlM(+mB5a~e=vWAq?M+buZj;4e`o1XlZN2Xi^*Ma@S zC#`+_O&OUcm}E>6qZ3rtjIVV!4?4rQf>^tXDTr`xWau~oCfeI0G@GEFbyKi zDj0E4=wkkK5M>^~52w971^JyeBrJHxhqTbFL=h(thti`IimvEWbQ7?ks^E3Qs)&-1 zsK`?ATak!|H;_5s8LC2KiLH~sveAYd_8R6}B5 zh2$f23IijHZ3ddb=uyZ93WoUw82dxCu0YU04irA#gx3XS3Gj|IDa((8W`zPwAMC)_ z#_;(r)CP=QFHV(k#zZ{>D#(IE$|b~u_lCS-8c{3}IGw`uTB9f@nKrxYLFRN`On4Ut zO3E**2}M9^E9G{oQCHx)?-fRl4pLu5bvd9;0}>`);acLFlQY2J6)2s)oTSDa;=ruq z2o6i4iSshRI22<|vNf;+Dp1K>*o=tP8p|m90w6Dm=sr5f0*s_?HnuX1 zfJuepCfHW&H^^WE#x|OlS?nKSG%!=?8&hP<2o}u4Hv$of63inMq7dj~+%Ln@1lrh3 zYyie*n#9JN)EYD>-wto&Id%Xv)T~#g0VtRZ`c$ER1LDf>$|2f7$zw_{U_Uep#o|~` zp-_*Gis&^DHwvK-x{9YzIM@u)Cux+HDp=|LZF$C({LBqP}-`IZ=LG7e4$Nf=ddK+WEYDuN5K@Gp36Vj&f*1_4zZ zlw3lLA((HsMLRN=cNOVXlgwP?UMMo`=|SVwq&~%(mBo*YjVYTxJG~4#HDz z!y_?>;PP5Qjf*m9TM+i+-A`zw;ssZ0u!yZ0A<^kL5vEiX0TH0w>kCfsC^25qRN$Id zg;7hGtS&5_LtlVs5pEZJ1+?g_i3$Uc0r&pJH#}q^@+jZMiBNU| z5g-l@C_6&1+aQ50c64Y3CEJYs4Bw!Kp#lnlQnFoi9Th$h7FEhqhOrcv?%|x`#<&B6 z6pG+EURM#i>;MZ25?G+%aU!XcQd_Xs#FK5pFQcncV_MkbeB;pky zpvWg6D}!(>PI5UFMzMm+U~~yrfz;Qu4*=5&g(EX$I)O8aFM$KVta!AN!%ODT!4gi_ z!^A}7AqF4VkYOx1x(+R+udot~*cL1rhMI5KK-uWRiX?)sCQ%Xb%oZ(Eq6)6mqAF>c z_?=;@Leya=@n2B{fe4RLcv!bBHNFl|(vA{b#gsMXEFspy&8oY6r1Jc zm--G47uto@3ewwA>wW|V%PLF6&N)ERBM8RJEPjR$FH{~mqf8bw==gwSr{f_M;kR=E za~}c5!+ZR@>P8CVa}TQ`&~t;#5xS9|ae})AcUg2JOb(bQou`O3`8lwd;2jv;*oNj| z8wwwWK*~wPu+xblm3Pk(kPw>$C^;o?W0l1YgC9G_tmSX2DimmA>&CYxpb^N56Ic2$ z!}t-BPbgRs%oK@2-}4>_3!)#S0W!;Q+2H4LU(x9BGg07z)CeHiTsVQ^Y6qkC@O}`dO7FObSEkMwoD_2s(xwMHAB;C*?Xml1t-2d7c;%7l!unXv{%Dc{$R+ zX=j*=6eFSgvX};7QtWLYI6MuY;96q;NQbo{s55L56onqb{w$CXlk|l?6GaOSx|*{S zF~8}E9(u}G_)r8{e55ycycgO6n7;swvB6|uzX-~YV=)*y6Xz0G)&b*+8QeGVggK5< zaZn6%=DcVQ?ZDK-oWgJm;>?22(S)zksJtSFjXj? z0t!c{WciWGOdKMI0H5NLXiowK#G3YuF{9ZegGWg*tpb+Y$1t5Ssh+=|L zMkFjJF9`HI!Ki}36X^_5VHA%cdVnUJMA0)00PrP(OSclzI&Z z*vtWLH)0O~^N!D<5Qm?J9IS{nkv7BVbTK5fA_74dyCjA|T2uHDdXCo6jW`8@40%}V z@?eE_coc(M4>K?rQX;~N0_WABtFLOL0V7g@DFuTfQ%B+Qniw+oNCSlq;1S|+2FxEU zgJdFpNtvYNtE~r_sPMaVa*zSz#dFpJ9ziVC`1~s`KWdP{3xevbJ8F;f}L1A#_@#JZ~lcdN8a^m_or`F9bbsFQiim3YjqsPe#GS9E#8jcnZZZ=7A#0F#HPz%PP=Zg(2oZL}KXcUxdLF zpog$g2$6AYrs<@DK4VX(CLHEN{vARS2*c8ab)t$08$Oy#(+Q3pc!dput;SgbpLGC) z4@N&@FO1U$ssR+N31MXVG&+eE&rc{QJ$*V{t!cy?HeqyZ@+%4!oKUzB&k|t1(ajN{ zaB+u&w#duGD6$@kKmz64!ESJr1q@;9ic98j1+iHsbq0)y<=9o4vg;|0@;uRZ!qNOy zyW5{cM*a3=m7EOP%~gLoIo`OQv zx~i|*GnCuF!ZV$HYz!yUACry$>b6%K?e})`zyE7Coo(R%|Gm-gv`5SKmp`aU5dWVy z*u}@}SJOrN59g0rcd`6qXNUMJE$aPId%;wHFNmwuMsZbNxMg|pU1uX3B-%?M8q3xf zL*vVXFIOM8m$Q1aT>$T&fBZ}C|7k0KJoqBT@WzABzwz|+$J0iuJ$ivqe}r4pM*Afk z&%Pwbki|D!ZFJuyHZq-#N*}ZKO9Z0xFS1L&tZO+xz5mgCTP!e6JTU75cdPzrxzV0) z{8xL@q9H)9sUBOG5{#u%zE z|G*#rkb-xh1sJQ(RR3#(+8FgG?T!Bi`RQ!dZlMZQ`)~Q*e?W!tC*%I{kM?_?A?hl^ z?khRIL(Qca2k6hgtl_BnKmL1TG@Z`A{G&N)L+7T<@PA|EJ6|vqYXLut=8V9XUmIrK z{<5=KC?4^^9l@{JzG~O$W`|GC45(U8BM#>m#a)T zlJ>S|ODe&%K@~lPf;c@uKnAX1$cr{QNY-k&AEJ$2^irQ*TX<^HM=I_jK0Su@>J zeXULRqxNyLa?#CJ-gcV%&*7t|lc$%vhf=iv)O>t8oZc62UK^gswDq)|zc|P}y=dHrSG}FZR;am|t0WS7GO=8wyeB6ff8~4>o6b*XRb$h$_4K;) zwD}z9JU2Us)5P=MxLdau`)AvoFFVua^YiA3dDSrbTJlw!?IgZ#U-a|E(7cw;WsQSj z<+Lyfc%SCAqw@zNlD`Y?w?ff+q42Vqn+3OLmjP{+jZKr|)#0L?D(K0M@7Xi(e(eMn z^WbT0`gQ*z@@1zuPK+<}q3eC~Td#7Fe8{e1kNxJ&OQ9JU^y%Tv$pmU^OI5c?BZcQj6V4?-JRJ@=IHEs z_t2+ZG+y@Fg~U;0mRv@LPqX;ysk1oQ_vp#?wVfHyB87VKpc>u&vNN8|5}oUbuX}%% z%FXtYtDVbWIT3u)=LhH6(4tho*m~GIIGRUaURnovZ)sR-W_GH1EgbSrPfq9N!F71- z4IP(~tyaOazg>>ZZqrBl#pZ=apDc&wIKOufZO>OOZ}xqSmsBl2JT6^4#7^>U{~&vG zd(mp0M7w!UV0xabZ}*bET+9A;IytHK7lGn1)Y_i!&#b-Ld3F2braV6#Uz+~u@nt64 zZ+v^YZoSNU`dxZIb#s$0nV3HpC)L`Sy>oWE)DBy7ye(Z5L*yIXOH`PNpY?X8N?&)jd1*b7NGFpYFVr&d;}Q zF3Ts&({EpPyy50+!y8HMm5Yb=IB}mUo<=fP<65$xnJxACVy}0QT!!^?Di2=g6}c`gZtQycuWf zkL4F{s2ttCFcQ^+Y`$&eqOT99Z=Jo-)k*&;R|`BI8fN987%%Qut`17OXE){P%R|u@ zI4VsC`r>(!d%jCwZF*D9zQ6P^Xq~)v!(VoW{fpw(!`WWGQHTxe^V#wC*5S~1aTqS? zsiV~6q1HINou`|(&C|=Ix3O3r*I&ws!p`H?(OW6?+N*qxTsF_k_myhnF?y0c$e$Mj zTbJ|5V|n?sv;WlY-WP4O66|f4drz0c=3wZ{dLNsUn72Es8&U6*_c0pmTzvZ)s`kRQ zM)5H8uwz7a$`MaHb#691-s1L7eN;-`&0|+L>5%vIv9st8FQeVe_}UI#b|0rNR?BZ} zpVwev?30P*sg8F05A&y|hi}!w>r1|BmDdXOZrVvv*tDPtl{x zdLT3p9Uq(hY4_WCJXD-EL$7bg#i)7HJ04H39(Jxmshk$Qdufyh(OCD|e;xWZh-YHW z?5xsm4nsS!;r&_X%vvl$k*`NDSAmm$&Tmehpvk@Tpw*$vb-_Ao)+qnp5H}_7;uSY$5TJ`nj3+?oHYqT7v zo?a@qv2S7)}|vL2-MLKb%zUJ}7NbG>WcOg~ z%RhX*+$s%Q5pQQ6T%8}?ymbAYWv}#7>PPLbE&ZX?>3MT|#^B=oqMKNJ!FuTRUX_Pe zn@_&_IQn&#T7EOewd2xRur-TK#(Gt|Ej$vBL1nPFa7d6r-WgV04)u?c5GJwefc2 zqH5-@4{yI7=stV7`^^s4FK1cvt8X`YG1*Tpf-mQ7EBMk$RKnfEqx@|+5`H;oSC8%X zQSbTeZV?z?9^03*v+85BlZzHEzwBIXJ-%GUw)S(Cc0GSOE#HPt6OTvG`w47}-}kUN zpJ?5&zT0^ow~7%xo%uGq-mY!-6YbtfxSBt_A9${(N0aBy+&8)iR1@Xa@x{$;DS!Mr zxZUjJbDQPr4rXOE`E@&XhlOBfzqPY*&!Uq%SWRjkUOwIrA9tgt<6^tF z?VCNtUiz_Uc-Z$93k9pSnuW?*v%8=Cc78YB{(4%?b&YcK)pJ|8-F-L?g&$sX*)Kcy z@x4~@wr#I6iEyWM)68V|vggM3!zyCVy8hnQ>-lWt4L-#p+V1#la+%7N9#4J4Vj!U% z-o^`W2Yx&9($m@xuUT&?t5=^Mo^g!*a?{y8PaT%`&7-Y$IFI#Zyjku%y(S(Tl~y=n zx4V<4yQaQ(*U5WkgExO5R#`odE8T2ySv$>*&UTi;$YyD)6wf{A#_aNG_40UmXBDlq zmh6PTjm<{BceQ+Z-kL>@=Bb^pTZz-k0a_`aghEfDMn0SypWfac7yMsKk?8sPTQ|P* zboM;FiDz%FkJFJ*XBgVsf7(AcZo84a*46wt7Q3Akd$Z7S+4?$v3?Igh#b7=J4NfhQH^-7O1bV}D?NSMG_$MB z`KBkPecgI08fUvZSLtHfn>tT?y?lv0b`DQ>Jy-F?-pkJQL+JFi^t2h;x_&uN-5lH5 z^4I)f)$V`U$>qusqqk`vN1K^w=j!WTxxO42FTH|!8+*PjF85bw(bY-1l3eY+)e3i- zFVqX(Jiq44{?6ptUKY<1-F#supEW1dvslnrc3uKE;pda$#keq?mp$7vBT)RZ(|<1N z!^`S}9mySB2gWe2NnCQ(LUCWdeP?B%e_18LR;*9Tiu3^XOVK`;rPNI z8EJG5GwcaOQkIyMDNs9A?|8_I=r(NleXFdr_|4 z78ZBoV8KWwR-Vn{qi*;)e^|Vl?OdeWy|-`nZuaW9(p?$~cu2b1oyn%K=-lhfFNQQDmQGheSy&qu-BbN4R#ExRrvWWhoek3mo-aG|lgVQsIr7aj`=@7K6Z@{W!I^eh zDSK=!T)wGZrejyH{*wozFx+j#Prly5^PX=Wr!G=mJ)WzktBZ%M=1acBE3uyDIXlao zCF0SGuai3iT{GG1g^nH|OZ@6J9SGL#{`uC@vg@73<5qMU_ML5>r_$4{#^Bz2zg3y- zwLN#sVK=%tUUq`R)k~~)+gKhOn|d&l)Vzc2-c7Biz1DIwGaCve6O)5*BVuXGr@~3x zD!}JIJ-CToO-DBot2LS!uQ%qtu^Z0X&EfIUPUdSQJ9~=XE}vhv=KGP`PUb$SU6gx4;*qrZF5?${i*{j`cKaW$<%lhPS|Lfp&(!IXF z-fH6|LHCI^09<~$pu{S*JcEUz!%eb1D)#mfbO*mee1Uq{TvlmNv_j2Rit>^uM_wo8z zkL=wRM!}2C>~I`4J(-4awR&p5OvCzFUh`a!$o-v>|*ZkdUvnK z)$0nDy=6-cHs>GY;M{jzhpie>K?Px|8M+c4LDc>dbi zyc|yNe1m9YSjYr+{MzhhT6->htDb$kO_qQ6u z>&#Oup%uGZS$)eFYdm&hC+Ym=pRO>m*uzE z^C)*wI7l_mgWuA|xR5UeZr~0s1Fd-HYS`-syG!l4csr|mwEnF(9tc%lPVc{^zhd|5 z(aK-T{coq`(?KkElr%cc!}M}1RSEVEa&RN|BlFVZb@Tc(K0CNS*}YsW6Svv7@~j!Z z**Q+tXRX+dcjxTeUem7LWv{Lejnsbmbocr3elh4qQnQmxuXDYJ9_ya8is8oQK zAixc4Jnm&e`SIy8e-}!6%&U=aHhnpMIvYH`<;%&yGJEt|w=34^ZsYX%;>wH-2iZ<- zceDHwxT{sXNpJ0@ck~#m9%IiGir+V^?F(4T@k4jdf43cpUmr(0mq#~+i}`$cx+n+A z+N<}tYc{dehzArQY29R&70> zZQTU!Ubp=(gJSCIw2?=Tb!XdWt=H<(+YDv~k+62^JuPhC4<8zK>+oA;-*Z&FAD7Le zct8E*+1?M{?9QtB$~f5Ei5%>OmM^#AegDI^Ua7RX8io5WVQ;az?LTaM9bYH^AC9hk zT{XXpU%|NuNkp0lV>D4H3L%m*G-y!m?*IM%-ha<|p7ZP-t@Rn#dF?}+drol}{)bGJ zm_7RUmy650i2AU@(O5%*2|!G7E6`5Jf=#Z=i|swsOB22IhtcoSRJ2NWH?7rWL))@S zZHG;Dc}P#EwLr3htW+*9R^7Dao8ta`n^+^jUOU4D+`L}Z_&#unD4e=dALEA)YQdCF zIC}UiZ@wD08J^X)W9(~={wgz@Duko6c-R{Ya{Q}Yx#Kzsh;Tr5e*yRti&`FKbaZ%- z>E(L80IvBDA^XQzM_clt!`4=%7$!da1dW%_ZANvnYB1S9n|M^K(rD*pREtm=h#m_W~{ZA0;0gNyUkzWV|Nq9)3}Px zjP-E%9^TeL@A)$?a0wmQ<36C7C-Pyemis$>pZ^TRmWs(Q`8;>g!0$esNj=|zjT{ZP z(Vgpzba*?@M$4=%F3+3}&n5%#I{kK^nm8G$%_c*SJ|bSd$$i6_``>lHwUCPH%@~TI zLOfEgH=S{VJFm;5T@|W1NjXY-xkN)N#TdFXm$}#Ot6K6~8s&9W9 znRgbizw_S?28vj}tj(@OnZQ@`2StbGtjE=7uzMy^&--K+2F4t6eNKfd`?_YQpZDfh zBS^2_Iv$u~=J2u1KJ+w9lE?kK0K%Vge=^1#GbiRDKE0Z|7x%!!?;xrw?;lrNexBCf zXmL{qETT>M%GR9?J?~6fv&-OCq29evyUQ}aA<*?#j@sWK14?f;M#*KaYx?-?J-f_& zzuP>Jz7d`CTJIucTlc0 zACD^q9kJ_v^p1u~EHl;99Oy7Xy4o)X;Z1$ar|3zXbFv=j&EHpF1d7Ju_0ANzeG+_H zQ?d(oAK&TbV{_6Mwch;KY9HY9cKO{uu2*7J8`dXw30>XmerKxl=ki(}a{BzI115g` z&IH{X{A#WC$^V|qdp6{~4>!hj1G;bLBYJ6^M@v}&nqSIKo7jA>JSzLb`+POK`kmI9 z;*xYHgLkvs*`SEEh&ISmI(qowP&$9Ac?#be2H;|&^8jkM_~DiuFDFA{Q0I(W@U> z6t2VCVR4TCAvIMFy0gcs5Ee^vP zUmC}NCCSH!ldoI2bLlVgGGZ$v?$UouS^M?xXkk13>-#UxPWZtP`PX;(`-`_YL@bp0 z(UL!3up(Pm2XoG|b;atp(Kb-69X!Jqht)a|&Om|YJ1_EYk=3hCJ-Lm$(eP(XznI{z z>QWD@FV^qEZqd2$C3)l1<=S4yi`3M|iVo%G+r( z>!FMcGl@%YTp6w0C4jB3165GCqsz+sZ2^s^!P-botLs_?ELJreECsI9hc0 z)6|<&`#m#wsBpD>wf#Y36Hv?3(q+Bvy*d4q$ohH(Z=w6A-avaq?0(;( zwfMN+L;E}BRhm3u>TO7Y0BqIc8dBt`+cuAZWCNwOuHsd zk^2#UVG9&{63ye}xjr6btH1e6@pp~SI{NxtNP8gcNd0*4Ed=?=G*a^WV4f2jf0jmv z25cBRwXFH+3hWoT&~$lCuUgkyua3ONJ+nLebiJX8Vx-xXc!+p#{SmtW*hm|EW(Jk= zW6Pcf{7@ALiUmKbl27i2xM42Nz``av5M7$kq9Sz*u4r-KwZWhLOFt10g zjmx0VXz$(LFfEIZ$y<3jdsq8=C_eW9ii1FU>DQc&Ho={*Tx#KU)YYMwR{j zl}+%$j&;U0mgde2bOtK`k0~{tARPVu*F0qTuAI-rAyi!d`c26xU7BjSMlWOkw1r8` zYK&X_FP3m^QgAiY$0y+lC;admB0q+hC8qgaU{KF~p3yqP{`FsD1U-1$D0%)vo)txs z!muP-Yl!D5>Rr_d{&PsEHG%dCDc0p4*ZGRlf}UOkXh6_>!YSaPo=>+)Cb*R~bqG$x zdwl@1D7xjSfPL9l%8MzvSjqIMYse)eYNdLq7Z_>W7*>nbgLN?L#3;1!*YV?5`y>9rC?Ppv9JA?!df_KkK^Q z$jExI+Kqd~pIChfV&gr02%p=ULKj;AY_9YqHFxjV4(!T>qLWjOBb0v=j|jE1lFv6`9AQVd zSM$%x4drj$!qX6V;_Ks_FzEK$S@g_aXkwv!@%pCKsb^4y+b8thWfVsvzFOuc<^g$n z_4da;cG4nnh@u2S2*bagblV`j)-it;jo<5Fd#|jfKb?~1y!jkl*T5BR{ynpyTr0}A z()Bd3jlePV+Glr5$BG6WFB4Axk-LY_9^FPoE7$x(ySieAv%6L6SFeljwuxK6NT_V2 zlGEvi*AbD{yYXA!YVsT%N1UK3Lj5mrDIO!*%z#ageuso`8> zuLKl2C+{vu8uwoeTizD}FY2uCH97{h`VJ|P@Ba`m`8PWzpR<&FtO)ID^o^|LX`Z%^ ze=@Em!_K^;YtE=t722b6kS_EM1e@DSHk{mGDXEj2(dTPMqbpx~ZjJWYq=jU!@3v}E zE?G(s;f-Z^!i<2PTqR!mIPL-7G+nH2(n!Fg4F^?w1h!s9eIc!v{;;lhA3(pKGj2uP zhaQSf!#7Cu6hPtnL+*KNHk&R2XYoxiB)Ye2VL2;+u+kJyhF z2`^lJ`>A=vuZ!~38JhdzjMQ!bQk7pg@dpwLt1~S2t0OV6D!tq2lg^tHxV*|=%IYfa ztkp(Nh-tF>Q1s6B)C7$3Woc3^4*?o)RrBg+AWO|Wh83>Sq zd|~@Cs-3Rqtp)(>w8>VZzcXZ`MN;|M-Idg@*8lSP<|ucQYI_n7&|jx3y>^MguIAqy zpm7!`Rio9ce*a|azxRzWl^pff?v=OeOA5-Wb`G(`YEsH)*mTx;MM}7jju)|CvaADC zCl4tE9ebs#*fJ{ZG91jyE1ghzaW$W9$Arm0-#!OC3oalRah9R;k~OcImvOB3=cUVR zo$N~Z&xW8hZO+mw{deS%;TX&I-*?xk`ng$u%f;n$F8R^rJ`u@xhT7&Os+uo@lDek!lXG|9zwRXz8NlS$Oxs-c;n}!ZT zyK5XO^Ri|}^X&M=iZLv|M&I68txV3p$nU1-MifB8XnaycUv27Aa|}=)^R_Kjli`xN z9rke^OV3p6*slx;754L+oIZvbuT37B!4J)Ei4CsfdAybkX`N)H?k4UVjjX;>gr5yu zoqFBA&Z^bFQFX6!bHC^)hH$;i!1tx7Pc`%o+`xR2q=m=O;~ty*LT}Vl7oN5$hfL8?A)s!Us!u{bPmVDUts&~)?$ZV2xedX3G%6K zrK{mns$TBNZ+SW`dfng9>i~NO>1>CG!T4{%Zu(>3@evm#GRvZOjJNald;HdR@bR$A z(Ta@^7+d+XDjg+Ihtz8x*q>2X`qi7eACsCJ6YqL4)|-Z>40q6cJGU8Rpp;F?m;I4+ z>>A@{$?gVuObidV6+v-#Wy+St#ozy$4j?`e~~t2|Kql^6*3bw$bXv?<`Q+??zKeFz{nx_w9|q+pPj8 zcsC($aZp0Gr^aG26yC*jyR@{^KSWxAUC=C?po_vk?5T^xEHYE}g9NuAz6G`C18hHXL$|p*?P3TZblTSRH`hMv?Q97zy{DO6yFQ_>NvtYtJ z&6zS{lLK-&`C}l+EH>^Zd5c4*&yhbKU{yEMiGzPE)vXq zFYa6u-EtW^AKX#njKg8c%@3+gQR6_8I(l=|+bo{ZjfSs8KGnvVCuKa}O%SmSwDtfyJv7y4B z>DobD9Chtr(pa=wSH_KVUGjpA$0k?cgMsu~UbHbY_Asj*S4-gOQ_DiG)R#Zwu5?Wi zm!$Sml-fn0s>bX@#n-vTQ!y97Prb! zBU*pcZO(uR%vLCbWjH8^foCBAWM;L6$i5M3?Ei(I_U&Lc=d*74uMSVaw+l+r$$co6 z6_zwXnxk_aiw0&PNN*!UnK6S){q_AQXq@3H*Kv`#_M&x?>bl9neY6CH53o}J8h?^R z-OedY^X&a;{MXjdV?Yxq3lh?EAa zSU9-f!gX*YJwK9iS^GQacgthDJ_ zKzvtw3q-OHN2rGnkCnzknhQyS(O9^Ony(+ zbq?W@>HYCmJQZh_GP~;#0KAzXXZ4Gg*=|3G?$$MfqRSEFVfv=BtE1v`N14oQ618u< zL08SQ@ThO=%Gi2%fSVtg4?eaewtMKmCp*-=z|-8xgB*TPYXSGB2`olKp_>h_Z>`^2WX`CAQL5@8T}L#)uq;5G+-;@MZ0F z2b(WfgX+z#XyK9J1;biJ+yWjRd;JNI<%l?8= zYv8t*V2RWV&GgpKRvOP2fbVk`+Cu99QxMNYWw8|P9OA3{oOr)`5T_QM z_FI>3^Zuw3&@7SzVtgZ}87h-AV#PL{S7+P}iEs1BH}IG~HV?xHH@s2#FGP&YY$Tfk zIe=_W3?TTm=gv+EQVE*j1#lmnp_{!x0`vlS|!H!l&+yo}t($WZee_kAhf0!6VT?nlS>Wyg}O>ZjM%8ttA3)w*Z8kxm|gx*eX8 z$um7*DqC8F&Tn7d3YsuJf-qe`qd&L%y`6j>PaD9Se>-WZel*rmt2^vIvzjKNB?=vj zZ{Q>U>NPa{ZKj&LanKL|>Vw(3H-DHiq%b3;{Y{g-UsvRNX%F`)+R%1kd@}4dznpui z9eAQLs?VDJU0kQ8J@$kU`+J}}-9j)9p!EGl=@LHshrsyX0Igt+q6iyvriEN95Hp<< zYx=Q=J160dddBY3^_n0LGD?ssfZsV!g3Nk3tGe7scu_SO&r7TYO@JKWUs%~ za@70T(yyap)L{-dvN}=K$$c=W2@pC~=cEK0&`1t#T>M(MfSR6z6m@qF@&eXUmD(4& zvD#8PUvl8ZA4+$nl9h13nF0SrH6Nhoj?EsFfj(WB(bfLG4+?>4yAt!S{s%8&XyqyPFnY=1Rkwqe`-asDB}*K7{iwz5N9uC-np=Nth4>qGqlJ>)cp+r(rMK}g7*zmh z9GX?zP8czy8W6m z&_r)>qv10-VY8ThbgJ?63L1k-J6~1|MhVj3Oa0=pk}BdPN&^1$)Pz6wrmB+kXdIfg zCUf^o>+Y)hf&do-DXcDhc~)yqYI_w-Z^rWRCnWMDQCg29)wPbd(%=2QwcSz0N)9*j zxt&G{PJn*LOk0TE_Gn2GdTmd)ceSauLw51syHmyDN4G-Fm<9-$1NNHR8xSjLxG#7E zE>n@2T@##Ed&Wv=B5H1!y8$9*D;k;=^gY`QFU6$&7;?X8Pim!(hixWte>Z<5`{sB~ zCvlaHCwv)y_J-+Uw!u7{O2PriC@ukE6kc`WjiKzEhn@6c7MoQC-&fnwlTN@VvR4D< zUA-T>u=0Efvp(}}Mx&`&y!WH3zD+}B*q*F^-fELO@8p}DkF_HGH1W(t6(qQ*3i zaXrr)r*-{3sD5;!+r4%^JG$arW;-~UUb~1Wh3M%KO_xuj;(~%mlRnEWxA|o3_lWlJ zAX^wkOCBdz+mb@8RX-S;-mL7-7h2YP>QgK63h?wn#6I-5o4PTljrh*E$6xQd26L{x zl%m7FeUf-fpr&64U8CmrXoY0wmagBp^;aGqD1Kt@C5 z%l>`JPG2!gBj>uJxJb0GZ@oABSATT-c5b+64@=zcad zG$?HMZiMkPle~6XwZBin|F}6I6E7TkQPMKKz#RLS-WjbN%Y=hSp2Wr975 zn=5Pth|_}HuF75Oy`*MkuqzW|#gNVVH$^gzJMPSQuimt0pO$2Gdu|{YJM6@-Q6=nz z;w7v!#&pTk$i=5)RpL5%vN;rUA{KeIBl|haQ~^3Lsh%pCMD+ACu^&Ky*a7}B5QC1| zJu5Npf?$aQgx;S!Yc~&u_epkuaE44H*41(eQ7~t)Pc+|>H*I)AMiEY4uZdZ`GhJ-` zb{2W2m=9Ru2+H4Amb1d?`%G!mdHO0qpLv<`{Jj{9~fB?XT|Da)!?&0F-xEbdh1?zL+APS~4iI+E$B)<*DyN$Min{Q(H5l^m zhU_$N8|Qs`q`K9N(b;8-DHk6dYI?O@k!n5Ie$bS|_DdSw%d=jW z)Z+l%!k=WNBaNo^CjW4dxhp-$f|HZFk>fSI6Alf?ME+`+r{Lp$!Cdol*yp-WwtOPA0u&ZGL3sc>$RbY== z-X@+tPqR7SlEl9w@o4+f$u3Fv$DguPeyMWq-P$a`mWDtdR&Uu~HwijyXw~d!*K9YB zmX*sy=B=Tpy^zQ6+d2tewqC3j79Ng@wrGi}L#cN;qQ!E&@W@phtT-X^CNsgh_KrSe zp3j@T0E+R#5oi~;A4z$~K9|N!E^K88TL0BL>TO-?HMsMSmX-417HSKMbDqB`0{vc5 zSy{A(>p!{xDVm3`KIn0!&Cgp=ayZ)Ya@9798S+AMYhV^tr~F(|SD=oz^{G&;EH}MT zOWkzY!;koE;2ad~P_}=nKSQbF+Cs0cu)?C+=a_ms5G2-ZUtf-+aZA5$SYvNRnvk+r z+bPE8QucJw$FZ|S=VDgr## z^+W$f>f=7}RK5FU9qmyb$|rz*)|T=)SSVqOuXOLP=DHM|nq)5&N?a}dAPEeEJ^;1@PHdsDg8*gNKAT~(*TYB?70 zow{*o%C^_3Q<2yE0X<2EnA2F$*>g6U9PHH%`P9RPGEkgpYFDu zrugeDPO3meRrc0M%w=^@-bAOy#Fa?7Da429Z`^+kiTkwlycvgWgKOQ3j@aFlIezb- z2Ha<-wkkc}XaHYT4eAX|VsOCs(e>Z6>RycfRcH=xKCIfP-22zPv_3`2U4^)L zG8C8!0=cPzHrUH)(2NQ~)>E`xZfW~t849|@>V>*U9v*6-J))0HPLn(t7Ush94CdHm zw}3!fDyG)<_gJ#B+&;S1%C%7|-1t{}63l2z zhhaw&{Cw4nJAnH%WdZlVh!b=*gr5(xulJuqJJMSJw*BV4h6T~WrO<5_@+s* z#qZ+2Rlf4O-0F|rT;7i-FS7>U%BB69ZFJNg7E9o+QS`T!Kd}YoSkJBeHLllwG1A&< zwt(r`3wAr+_*Qp28g6<%u!lG0^@TH!1VTKYF~9n2*3Yxo8+Ne25-&G#cM|0Br=Djw z43}>|v5>(6?edGcJ935+P{lzrrCWv;%u&N{Q&8MV2glz=>(ZYBi$19D;9T-v0CluZx!P^j+~%K|^Lc<$l-p!ipUOp^ z2@_9x^jr2Iqil2nZTAp}m1*y+zd%NS{rN-ml&^D0_kIy8&oKxXFzdPE{(DDNxQ!H0*Fv_(Cv1Fc#-Prn=d zNTSaQiuM*|K2MpyA+o@0a^*eey*}1(91f7Lb(3%Z2KRFf0 zxwcvoGNWhI+<$^RND3lPG&+NUNF{b_?Rl8(k1-VW1{*sw3OS1e;-IjM;Jm)@&{afx=js54%@+-qV( zP4ds$-wM>Q=&T;LYmyT(M^BU1f=x5-cIg5nKqW~Ka2T}*FFv;JS}Ew`JN*FT}} zQEPL_o7E@48z+Z`)7b`~mmY>~SMMl$jOHP6T@dss`QJ|VW&psW}$Zl%|GY-h1x7PX!8#E1HQO>CMCFCpw>;)_Y6 zsrU@?hcXB6Pma~}iw-YO^dB;pEO|Hh;}%P-!X{93?1M&81GEsXUF_U#Ewh+bKI*DP*^Yl>hKcmHe)#b!T&+cy@p7jh265r}CmKRciD2%^&wogt4v0lj=!gclQd(xH|BL#OiumVH$-rF?1AO zjx^?+rVFgor`xOEI?&N2R@$PXzf;`-W{;lp`gIimi7M7Zh43Zf2q^!DBwm- z7yJUfTXDMA*d@+_HMlRmmdk$bXm9`9bAFISBwhR*V8cm;nXIBk_YGaz+H%qs*Q-*6 zn0vkaAs#1QuGLPPC#K=zQw0>_M072P1Fyo?xKux;O^=F12p$sm%iC_;rVix|6hMfou;H!qY({KBv8d z2Z&#ESS{`YTmsA-8eLNq0QW=pbY4x#?qNg4@YAZlhfL-9AdU3JmWjVpwU!nqU0nL@Gs#~5HcM}mzAEp5wp?G|;D00A_{)A*M5$vbvL{#F*i7X8ORpf*VR`)hjg$>R z>u&9Es}$j$7gi=m46R_`R8*WJeH)(U?2?JH^-sAPHbjKz7n4G<&X$}M57CofByX1u#BZ& zws)M3BQM&mk@5f@mP_mX$kK^Yc{T-kzu3miS_O|*ploq2%z%F7A+wKT?a zpcc&0b8KN;Lwj$+R*kFS;5tXuZj}BQrHuZBUR8ws#!~Mdn#1qAaXuV>aSPrKF@7A( zPA%%uOTFAV542M;NMpD5kv9E(fPpMr)SgM_IwGMLyV3IRqylw490HSc)+(`EpTYwremwfQ@s`F6L(d+qcurpo0_uoK9=!&|? zpuzBiZEXg1x|0qB*lRLsdpmkK4JyW);C%Y@8@zbP(Qo{)H<9bfh@az|6E2m2S9n1` z?%}T!91vH1{@)XwsB4VBMI`wKMgP3iy@87|BjOL>Q&)4lu-)1pR ziqFTJo||)=VMTZ|Oz8DGCmPcIHibeFGy*$z|3=&e77VYk8vl9s&a`*CjKcJ6@Bym= z9p><D4MnkGF^1r1}B-T|3%t zNZ$IWO*LG&B5g9v77Q1B$}usbDW$;Z(et`rmP(E&>OE%T?Cu~z)as+rulUlt#)a;? zW0p}^Rol{|$c85OT0C3TpBI!F>^e((@b?tE>uW#!h@H6q`5~~q3Ak}kE_09Iz9*Hg zzU%ecr~TUPk&}H`h+HKm&HoVW15Galr`D&T$g|=rcdY8q1cYBCN0&~G{3$aq~a=fgNm?(gaJpDTBX|HjRnEX+> zB$HNWS6by&t%$~l5#-m4E(S;(5>n|&@E=1MG(otv=E@rfnd{KxYfnzCe5Z9+yM}z| z`J0<|T{kyd7X^mbCl}4~?g3`6@Z@hySodU&wT&6xmHelo3#pc0%fv3>v;3wlt z6Fqree>dXba*nIEaSIZ4)^p)(tLdeZGO5%~l%_XAcLV0VbnBfHrTLrveS&87ziz@i z9hgNeyI9*bKtJ^Zl)KlcrbZ2SK@b{Jor-%^s(juSYO@DIY_n7a3; z73yzN>q&qkzc7rgF?P9Qr_?nA*8oX@)lNPEA2Q_${P$PuMGRX#Bt5F{vUeDsP;k*v z#=_`SZ4fJZ(L1ag?9`Y}Gz)JUvvG@lUFEYf82l>h2VgM1rU5h_%q!jGL!Xz%Nc5{} z^>X7E0pH*w_r8Ia=wM`lLz}Y7YGX%APnC6g3Sa#pmNXs6L?fufSA*wO%I!`pL2dcK z4)o1WWb4<~{8%%-bEQ+SfUNa0aeO5h|Jn0N<19>QCUHz4Ga3x?$ z(PH3_uAQ^IQ<&aT9$!g=pR}=K?a-92#P_(m6XE`E=EL{eDJ|Kp>!95f_vIIP(-Mux z32@Fqv3KVN$+OIHQk^*Krrq&&rnZAB;5t^wfGpgc8h^72|F!vm{PUQ}+{_l6iiPLrH0sM;dY5Pl?Thn00#JCGnbaQT*zGAHAU zI!9=4#`-y+VK>e~{I{r_cUAuFs<)AG8tD%u=41rpzo6d$!c}P;bQ?-r!LnTg=;h5t zR)ziYUTUw_P2&MK_XcwV7dtWs=;M|&yMtO_ef^Q_B^vUnssb>WM?j1>ex%- zkJ+tW8;_Xv8KmRv6d(}k+XHCat__41{jsC%>)mBl0^d4&c`1W#!n3+l58px!ysfi+ z)ILEl);G!?E*pJ%NHuCp{?yj9LpbMGTp5gerK~oWUO?>$ z--O|}=((LSa0#S2_w2nXf`&FiGwEa}gG(l#?V0X`ewO{+&T*;1bw%R(YYeTp&k;yb zs(>?LJkrencGnZQZquj?fZ6V^`-l0g{hW-Q5?TPyqC$cO=k(M+jvlt+s z+#0K(z13Rpo&#dA6E>1IL6(~`YNPGtbCY#1=Y=HJ2jfkrP_-9h3f;zGEq)uf%JEz} zy4RC5cFYHDjcL$GC5vWQiD7;Z@|Kq#( z)O^W)Z|0tx=@mP$UD)c#Oj{SrWthn61vuYzLrOddZJeH`>`NVF6BP9{?6eLhYk@7- z9iKfZPD-sx<5VtjFL(T#yx&&@D7~9saRXvXeznqB(j{ga{p;zFcf7!XNsdQeoy`N< z^Fo?M=4_tJ``TV5{kg>3FsFd_-=b|Lux@H*HQ7|{79i22R{~eB{#vJZp8v5R{SMU8 z5OZhYwq5Lm7xkbp<}=m1HTb*S+Hae>Z!a*t5pF#wG%j=(cwl>_Neb0Q<25U1j@M+Z=0+ze5M=Z@WD$q`uFcY7($=ssapyHzv2=Lsrp9-hXgrQ5y!1GTkYy zo}4vs1QAZ{(c*e`f;6AUlk5GsPlZMEv%7A*KphBfQFp|gk#~K}ozsIK=^p~R_*RMg1{jrs7Wsm@zR!;7_3@(I(>pyq9c#XKu zK$@y=)jBll!Tbi@M|Pioer1A!W6gb;)vE@EGMc$&+;b-&V1UA*I zvz=SX6KYFZ-Xt?znWC^nm@*(41t)ILRQLVEPL}E$pBYh{Xypu z_FC{;3wfkVZ2Gssn!^uytWy3LFtxtq;`{WST~lK)y;*hVvh!O~Dz$_cO*#@b@bZlf z-sJC6OBuWWIu}fLGzFI%tH-KAuDte_pLX&mGw;&1>8%=>&mp)A+BUi^(-+3Kxc*vB z&N_0zkpMoNSOKebEp@V(dhG93q~K^F(FZN(v{X7aK{w&o+=kr&*PI?5o#O}jhq%gd zw!PjG0x{~*g%|+UC=2T~{PqVOKI5XUaxLbW$T*3t#@7Nodx?K-&?uD zH7OyLqw*u$@w?aLb~h)hlz6MIwFl^83eK!N`A5r<1w>qS!X8~euMXAnt8OUE{eB)d z&r5*tvJM}E1AVm{ZV_8cPwL_xq_9A6W#4o+#%#@gj_I7a0ue>5Zxqqq8R=g0fu>s_ z!G(~-4_U|sp{8}`NdZ1CAC@m_Wq)Y;XR;>O9v16oX$hRp5T6PqVbkjDjptZc=tdz` z+84cNfA}neRQ;0#w+HY`{ww&~CBas%4NprNNKKmsj2Eih@=tr&9sVBASw&jHpp?8O zcm8X#w9EnS{~VCGqXVr_Xj9vR%Qr*n=Bx{;L+G7-sb++~;C<;=SJWLne228%p2^}g z2=+eTTMCtSzc{*}YYTD?%@bqToRW>JN}>+`E;7Dn18T=f8*a*NAQhl->C84DefTzq z_t2rEI*%A0JGU#$sulJ39fz-Y_$C;{)AGsX>Q1@0|Bi;i)eFN*(hbYAOeW*w127U#*g2x_&b{}kwJb`k@~Z(Q2h=5E=&uOO>U1b1gMC~U9?loPcN&N z(G+ghFFzh!Pfuicgv>I6XmU*@^3(dI3diJ2U&w{=o;|zXxddnBR8xJg`5P%--^R*_ zwP6cm;`dqonJ(zz)4sMiSxJRx#=ldpeJrDQF6lLgPg817Ufk{2s#XZ<^SD=N|LyIX zd%FX247U>-hi&M>U?xeM$)$-xD>@7FT zIab{ogZ{Zk`s2i|zLa&^b1Ls)9kXOg+?Uteg$gG!dhU0s!k<_-pJ0Xio)2{6ZbI@Re(CWBGnuNDB5@v`;^U z+oAH-wL^Tt#JSTh7sp(hgBaRgE%)ZstZVc}k2F^rt>5LI{kJ@^rGNLA>3DwMhzXW@ zzfOPAKaSksc{D5CT6{=yrztJ0hf|0pKB$H?tcc5HE%7Jw`*MBTpR3h)@mEf9Baw)DLhudCYuWV;UZA6^sR`46!LqXaHjPSRc2Z@|Tj zd#b}WlNr2_o0mYJ_?zI-kf@O>u)xmhm z-N!v|KhLY#s9K|c8U{%gE2biFV@>{22QuxgLc9l&5@!A!j~s?2?E0CsZabq?*%-@4 zm-wS?oC7XU+Hj{50ELWh{@cn=$;v`tDvO!lBJJH}H12NI_oCWM4|A?js&4qh{rtNA z{b8(Q)7`0FQt&T8?0^qb)I$f|^EqD$~ZC_RM7W5`JF zSNioJzt5GO>Pu~v3}%z`<5%rUqIE$ph{JsYEX&7Ay{WCIn13i=jC7K{a(f4~&DU2% zl+$&bO%lsWo=T$$V zQ$;;(QuZW%Xk<3QgSG08nYjihh>r**ybH`Iw zynO@!x9HqqTl|pt_YBXzioFlF+;Z%7=G&zCFt77*;j%dw4_a~6YcyXIePlX7P45*8 zgn3s4Z=-&C&tut-%y2NuZ}rg9fa8Gfk{IdB>_0P*RpG> z%0xW;N+QjjkrO)|wyg#Jld;CUtlSs;0ypQc&fI!ySGQC8VjSDi3k89Dw~FWA-!Cl^ zr%pn}olv@+a>Ssq{DZE}`>HYKooqBdBwN^76jICSdg*qrAYSqlWAo6SpY6!IQi`}W zkq$i@+_uhlbQ)5C(!i{pGqE2B%~5Br)dl zK7LDA&D|Mqt@UiT@(-M5e4}eU@dgcp3XcibA^VC@jr#n=DI`+WZEcGd*>^H{-|y;j zvOO1>hBjU1yg_6A84bj5zh;KxC4IRVyF)Ya6rHZmP{ElPC5O0NXEMCutE3|vi|#3F z6y`1QR0xn}{*g5=ttvf|T=2mT-?x11)tFZ;X229l-qY4zlB4^=!o{1VYlN8oc^vk3 z&p6ct8h#TK1k|M-3<>HA@?J<=cWXEERf|KahPBA=^MapuEBBK2ZnL?Q3Zgnp7b6S1 zIy{Dz`Oo9Iz{sa%bnqrL{B`ENUq3!O6SYlqm$Y4Adt!(--O0e-e-BTaQ$6z07XNdX zBBYuPn$*3`w0@mJ+G|E#PaOW89@mv8!Zd#Gtby-f|J6QR@n+V#T-|=KFQWg@`Q$Zx z%ueL&(IzLqNxWy67BkJA=NV^f7vo_qK-U z_-#AlK!g34TQBumS!L*dut`$&;kGi=n3+-htND+mJ75cb?ai2X(Z?5v8J1WiSRc7z z6TJ(j-2S1uJ)A&hh`e5}VNhXO!0@WqAw>HcHHXq~>5l)N|0BR6cZgM4=dSx;_FUF+ zMc;y5ui){!m$mnzL%W8Jm|vPFcX|8zY@k6QzcYkE=~RO3+riu?INMX|w=%2u%A>79 zp!L0C4Ly3WCT6u+TZ}3&^_hovc%u2^>W@0z>_2pa>H3VyTvv*#FTvTvaA^%z1x91i z46I<;LcQMxOSD}EbNgEAfcn79C#?~YV+GZ48`~Djx44gcD}D@8K-Xh@Om;JZKIrANUwP?#fBYz7GzL)h_`n9fc?Q~pxFY)UVsIE2XkA^^zfIS#4BfMV|JHbch?kOO|Ftp@m&U~0e%!@U#bMimhlXL2^V2V zNb?}%a&RkL{dPa^tYJ0Ca`h>`8e^3$_e)xa@Hb!lcKJ>!j=M&O`I+E<`MbEAQ)54R zj~;g9jzNe6Oh}VGS6fRs#Xf*moE{biz)!n5Ldw6`8M2?)-&I_kkL~t1OzNVZ)$*M$`|`LUTy`skoueHp6bUk&}eViQZlEzJ;^v>B{RBC+l0Pos7qT z4;RC>G<(vG<+yMUj4~sA-XYTM(usTLV<5Jvn=`wH=cxXq&Lp6!ZxLOEJ>IB7*S%=< z(Ub>b*Tj`?gAunf>SU=Id*-3J;%k$lKz;|pq22Y@X}Kl+jz>E#U5+n$X;h~VT(-u8 z@pL9tz&FkTKjlVsXRo<=Ub-jME#(>;WY~@b;+L&G7tr2rylJVHoh~eEv<~B`c{oxf zbW)qIp54-}cKbVztNg1`=eTiyqL=pQL_h1;4&7wRSIdYd+$-VFBx`Q+KKWL@Nni6| zQlSzi)+;@>%M64kRi=(90qOKBbf|DS(mWKn8Fts22YBRcnPa3RjPU!RD_YEVD(ZTgdl{R>RnCmG%_eW27T zk1&2P$CF^Y!@oPo&&U0=(0nxN^PUtS^kLm}m77{W z`YVf>98tS=ENouw+Gu)OKic-377lOwj{W$??6ixOzQfOscKqiB<(t>sCU$*E zvmobBHl?nqe6ed@^f9$xM5^7{=F|oQZVx%W^8~DxbIm2+b3wI+-Ab)Os-Q+2;(c8) zZT`UoNDqQr6VdFF{hKn5W}@pA@Mo?nF`#?3H8JdaL@#CY_7{HD;;vE1+kNR$Z=R5+ z=mZBJl^5oNp)>Iansy&_%Z=`xg%u&lwB`%h9B!j$;8`K zy}1>?i*olHm*x7wb9}AQm?OqkX>8Ba+-?KfxK_>o$;)f!*E=ln*Xwre44xdYoc331 zceDWvx4CIu7AO`C?NOZ6SoU?>C%5_#tsa0>B7phV8okP!NpPvuhd#6KuEGa+BbMNa zM@IeY>#6(st}se`+ql>I{AuGSNmMv3h4RlKZ&F zHVzv^t3RM#*j3`@`e0vDBeW^b5!@zFz|!`-12wBN!~FIEOZ_y2tA_DR+{NZQ@y%hc z@#Xs$^|8%Aa~b->`MNUbz|F!geAY32GAp-3`xA^5axgv{Q>S()T9tI*)DRdhh>3v3 z_vAU6?^oMxX0}@l%*ruG!jMS zTAE(lv`?7_pSN#^;9x19#3MGtd1cEXG6y7zitU|3ZCF=o3V6Yp+5n%h%CR=z+&`PF z)qb@n!xVMC-yTG2-rz+5Nk`ZuwK3&a&)cx=cDMQ6W-A@tdWKXn$P}tiF5Ryah_;K_ zWVykEGVH{;$L!MQmD*poGv54x_^MDvdGHqmtTyHLBvfq~tL+h=)Rooy(GVGb22u#i z24*y|E|AEf3v{}WEU-uDX0O_tR8xOm51!1+i~i)|TWYTtaK6kx14*EW%Fju5on<6C z+U8wh9CBUrRbs82t5}Y(#H{UJlybn>9*l>wcWm|bvoH{{ygHpQYy(y zc-+p?^VUIk+;)7;eBrl+yV&($idWf$Q)YCN({)9?Xtaa3!w^Vm{!Z>^_PZJs*5S+1 zJDdIko01sQS4MC5A0O>TvSK^`-8Dz}jo(#I-b#Wu43f1V zvytji672(f6jhwn>{iZiPMd5Z9I9H|3-EkoPcuSWzK?vm-A4*9T_|(-E9fEJ%yp2>9&V2-57IKg1)d8)lo#x)PdN6I` zM`A^*7tfx^$7FXHY2aC()db++4=hhg&pqjcx`(HkQ%6(^tkY`(_-2uAmYSVt)k|b~ z8GO?lY(~OcsXDEmzgA0xe%S+{{7#$I1atT37EV+nzr9GStNrws=AyJXK3-jCupeWy zh+onq{#We{B->H$p=iV-bd-RN;r1(CgF~+h%r>%HRPvJwOt40u%Ksg(6KTzEm0({R zUGdBNnXuxNek*0Q zQJ~l#TVF%n(W3{2QO)y~k{16O^#CXY-%BZ(l9Rhp1tbb^$vXP|iwrB|r)KRB<=su4 zwZzYsl6OO4*k`$(@w^zHH(0Bm-^JT4LOWGs1AIHEnL8D-G1I4O`L#-Apq@k7_x@CV zNYH~5TO&r)8ygtuiOB#nYn-7xqD{^s1E%LMaVCwHnINP9WzMOc4Y z_vxS2W|wJxK4GMlH!S}Ffhs=Bi#0UHjJwNTv2T~^^T9ys5YvtYUXs=?Ny8I{*x!m zWqe&y<8f)xe)rs?rwq{hfpT9p=0~G+xj4k&6MH@MdmU^>Sl8z^N8zt=Owr)_*Mp-} z@uUv+XmOb5o9z(bEA>Kf{}<3)mWz z26&A&@Xfe=PkPfL8Zh2AfB+!&9GofkIxP2>IM<8D>;YSOT2{vqvx2OI>tBN}g=WjrTS=IU)Dd&o|}_mXt$zxHjs^rYy5kV%oQSI{#+1S+j#5-+ft)}i$ZyY||H zTod0++C`K;fCQ747jkGFDDp3^P9t!!#OH?$?@f;UiDwE|q4B>%Bza`C|J)`H)-~nCX76#ieY- zKRQ{BOU^H*(`mK8$Oj;cQs|*l!?vH?8&0wN{N95@IUA_=NnfO+-tDl4POy2YLHonV zNU(P69;UhNb2Mkm9j9Dq@fm&0bw{Vad%Ml@4Rbo6U!6+&vnfS|a=$&p5<}}34Pn23 zEycs~8-B@hY1Zv_=!czjw&>wC{Iwb~cwO~#?t0O&(YP@v(6j2wkmHiguX1|j)W8bM z3ec#d#_YG=3t4h02fRJqt~PtmD;^z@DC}E@0eUiD&wFvuxPhKbr&Sc%$U}QeDZY2} z){t-w?N$dY7CB6Iz3T`JP7Z5u&ZsmZu%k6d_fzSKXrrWB`F@A%kZcAm^=xied}Z%U zrtjh^hrKmskc)eTWMj3F2q-kVRL_TPeTBBl720Bv)L$RQvp>oA*T)fOT&GjMd*1fu zMQ=j{jY&?cAt`bck{2D!!w`lN-hYs)w=3Nj)1|SKz*thX0Nxf^*S_wb}~O6 z2@;{L&j6Vuz}=$S(OgXkwRwIfnT0Qp;p{Qwg8nTlKRj}w)OXk9F?jALH!UAeQ++ak z98Ms%zt6P1!50%_(i#}H6l16l{3AX9v_z z-k=hxCGhp7>sjX6>-UkPR$LdMh3BUyj-pmg-O1Ht#l>ZAmA_5;Gx zP^xh-OeJLeD{(yZHsDE;_WKgDLqx`z79N*$cr9?9*YNnfmkRa8sC(&M=@4$>g7yt~ z;wb_PP)=vP$6`jIt<8zmg(Y=6z*idt%k+J>2iUB7M{gz(>u$m8Y%QY5HtNhg&mK5# ze*O$%@~qLv;0o01LnQ0Pk$IrZ)M-f}WUM;8^Q%64+0=zKRb7U4tLDmmMmtCAV`2Ze zU4p?KZ;FpdcZH)^*$L}DrT!%c^0XoD*Fxr5c`${qtSh&hy4}JcqNgQ$rI|}lFk9XT3f)~r%$i{@*`$T+g4T*J%xOIUazA_Q=CWHYJuVgSS_I$z zqVhKm_2bik+wFPLEVq{DDYx@?0DJN^(WTG*`QBV;*sXw)vXrvt$?;*rFL`|pUrF_u z53c*dpuFTu5QaF1AE&n@P3>M@@X~fv7Ve^5%6Ch8JzL{a#f!?tOPP?lDqHeyWnn&g zHVMeA0_C4{H?3{f!ge;*`!Z6JfldjV5ve40984Wrt7>1be>oAVC}t}vGs6=)|T ziwepQvp%?dW7lmgVTM`KCON*WJ~Ihv+V0C1vgE~3x(lo7Z#&$-D%^#6 z&Nv=Asi=9-;d^DVETG#u1W0Q&Mtp7zhuY`c+>D3ts8{eFODCUna#Z~XH;ajz9{2ut zoJ38kcm)dI=a%;;>!q|}e{R*mH1;C>A@2a-fWxd&3+DV%E&gpcnG~KDSEuCXEd5=3 zO0JR2?`o0Z(MPYpVQB6;ccah>(Y3|^Q-xqh*V4Okh}?X?)FrCdi><&qxw*{smQm+J ze=^OQ{PjEV`P`&K%o5-wZ{4VZ_d?fVWr0R`)wD~R`kHOlqlkGvY7y-O?) zrxI4*jf;o9bF{di3@7rnptnoSO$5EN0yp4_G4Vc_K^i_*uL_+N*Uru;(xUAe&BJ{k zysq#%kBl{6s#B06g8XvhZXwfBlik1a+Pb+~eyP*zHVm%o;}DC?$Lg_=M(|V;dw+{H zRcybrU4M6pdanhx+OKs=H(I+})nC)6+qW;qQTiSn&f(!X;hlZ?-Y-1P3*P>W)7(B- zhHQ{-wuRxTAb;0c^muvYvuw57&zpW(4y3de8CK zI^Xm8n%rHtvv>jR)z^5odv$a8-|^3auIajEtSJ_Rghu?q#uw&P@nFA{|g(Z$g~YjyoT(lEcc<7*yxNUCet z_W#7XI5}oj{{nq@Q&j@qh$lasB42A8_v@Rr65Xl2Dl?LbpJTDx#&2mu&EeGZtfYii zLo^$`l*x5^N(KDX`W4DaML>bDMT%01KuI}RCmMb7xRO`ealoO9Sj z=a*7AGuR<7%5~V9mi>y+Mu*(+Fqe{A{)iCm{?VUoPVd3Ay8QBMMe=6VGdA3QZj%3< z_0Z#A2~IH)Zf3pOct38#+ClsT&)-|$43uvMnMy+GBUR+KACh7i{=Maw5EJYl5+7Um zQWc0zqtFk_{Ip(&_{Th%vEk9bpu0<@Jd9f9D96ZI4Dk;hW|(QUP+|#XDwogxC{?p) zddwG|n-7?7kUSP^RisbOw(rl9e$2-6fB_Y#DI#C>>Z{jc>sxs?I*6tp%}IR<1+&qy zyIdZNn-Td_%unfT7=u9pwr}-1Y3pZyxK29u>jAAz)?YTg{b=@n9Vo4^ZeoC?OhF0P zVgZ1j{L?CTg>-!$Zf^Vw42KM@Htlh*1740rJ{&>JTK}`7`KjeQ`Pd)L#>6|Z1=a;g*So8 z0KRq=vNZXqAOzuZ8;}_yS?=n2ndhZ+~&Q8`OkA}u%B=io~ zzb+->|8yACEfloAGh5uN|4NoH09y4ohQSEo&Def_N9ChiqsKIQ*@OuKy=+3dW5LOQT}1RHxY-61w(2lrtqIRZ0a zwlmdxw)3JzgZ*gHdkTePT5?neAFZ`n?OLIM8Z|7i;Qqw}08M3&s(ZH4W=hrpljv@h!+Jcw#0mm2nH0_O$CVXNM1j$?2bwcDZ{&!yyw<=dSyoitJ?9Ivq zG3(W45nId;8wz@Kzwf?xAO}ObH{KPt*T;6gU#!DBaoc{ruN&gbjao~uUuV>NKZ0bx zh@T78znw*R%fj3i^{gJ_2Zcc8#$&wJ!sok-w%}k@dfQ3LsDB=G^tKh;mlD~zHvf9$ zRS3ATSP(MBAuNX;dnp48r+U?AI{Ea#)}dB)KYPoUx#TY3+>e9V{kW&yf@FMaC7EK~ z6W>d8e0!L7!99%I#k?55ha++UcMt2il9GJ`dXm%|8$HEsN68NrVtjr9A{}pp+{Bj# zqheu;O^1>gp7auR8vb(-sYq3Gb56kgg)v36<>zHrA?nh!bw>{MF-Ot$d<7d+cg4b* z>NZKa`fB&aAHV26YE_>3;}f?ORUi+7XZ>RkPWY}?s{49*-h-RDby_p~^1q%D9I2L0 za2%Ee9>oMo(wT&~jop(zP3H6&{Y_J|i5-4pw0j-i#t(67q+m{Sr-EhVMp)2>YTKF% zL*ejlAGe?F$dcsiXXm$^QL>%YH2!`uVEb12c4lkOMqFN4F~xh6ki20&ok3ptUm~N@ zT%4w;XZK-HfJzg(a+dy)cG*KZ-;ph zD>h!Axz!w`7nR-O=U{HLU5N13kJ_2oJPDvMX*+w|lYd=l^OOzZ>uQEx&gl{|uIpV4 z3>W~=o#H1X4dp@O6*Hq=r-LI%&o+%2&9Zmg0mu>WIm zE&TivNPdOoJyZF^Uhw9heElIsHix-iR_{{vT76V#KPOb82BlsHY};3_S*P2`{hAKa z4#4HL`=Z;`I-|!>GJuG1=h}qSTTF|c+OWrk+Pv4@`Z9&He^UAP?2eIe+JyZ}a_owS zPj2*W*T&oli`Uk)C$*AUD=DB;x+Es6toNt?q6WvCui+DHc;QkT&d(kmM$1pHu|Fqg zzu2PPQo-yIglC%`S!O;S8I;`58mdLiCaBi*@HhXq4(sVU=Z{paf=wAtzCwfSheXhO z5Jx)q-c?G+!FQHhxnP4npY%6r$n^(yBP7m`4YYUM)SG1T9Esv7a7!vFM0Acc2b-Yz6tI@r4azgSwPcmzYSIqif4q-~Uwbn9D=jwbJ}JQiQECn< zg~-WhULr|)G=@ZWV*=X^d)xp|fz5bg&xxMM-O>a?9v^dc^XUXwXcir51QY$|| ztQxjcI;&VlRGp3QH8pUm!{*0LiT*A=F}EnlGn+@he|8_A`uqGonl;OGYPj#8*j6`37wRx- zdTZg`9mY*mmfp{n=vkE$g*=yR!$~*yU&Z?i*>#1Np5+-yN<7&UD~Ga>6y={cN_+K z?Qt)UD{u#MRqHlcZsos`q*R(Y)G^d>owrq;sy2QRJr=dS!~hpvzh zEq=_oxoh8=LXX}t8cuFU2npyry*SQ26G~vz@%)mX_t(HwIp=lQ@_4;?!Kxc5!>H!j zjW%wUaz~W8OB;MjtafY{OPkMv<;>e!vpYUWx9!0q72ztv6VvJ54DZmM#wJ*njyQla ztkrQT_Sx3um1#rh{Q!n)q=eiSjIHp?!r8dxen+ba$TaRpc&^-OrvNOgBzK(8p)pSG ztG7@JrQ&NHZ~my5cva@a_J+6Um4D8nGoj^L0PWh!3D~zGjY(A^4 zg<6ad;k(}|+rz)(%4-fYE4M5Mzx_`)ybu2VG%dPg);Wkv_oAwCj)Fm;2(hoMiyy1f zLPzk3Fu+5|4_xx3No(qfYsIU=Z%19YR{~^aM5{8ttWJty)60d{301Xq^|yM|9$t5a zIYR5rEp)L)rkTgiR4nYwe;zVgRAc9}P-((FHY0=pm}i&~YoG4o1?XmWl`;t}!=SI{8eYV`de`a2df>0V1s#VYeEog;8`omV z#l-@}9Nsj!hPg>8_+AFrzQ8W`4yRAy#C`vwi^|+OKOgf0O{!qSRfdAzz3WU}Z`3|< zS`(Kkf3t7W{f9Q5A&t0&b=CwrU)X={x#V!3!_$IyqPuko-VZooh0%NVUrxd~sJ zS=JI#vqDdv)Ne$m<;nw!9QC|fjWq5?gxK@%q~et~>w7xharsWJB9=)EVj*M>ZXT=*OH{oDaah-!HO znUONL*okO&X_Rz(zBPGn?n1-NJePxNfZyyX^hMcDEfb>>h2y5aD`xXTer@ts{A zVKHlMaOf}m14xXLIx_vNqi5=yA8^=!)Ku$)8M;nSX~sKOil;EAA2PX5kMhYnjlir8 zg^|+ZTIQ8#3?7m~^d)~8V|~A<51FAT$;pZ64@7$ty~FC@m>GRJxWG8G`xw0-i9e@T zb?y{xeR8yG{*G3R>Tv>wA-#&Y+YAf~jdrobjeyphn@w)2DmiDo@~ zbAMY%348(d&d8O1Vd>mn@qpavgh!-^OUh=XMZ1&!E9t z-kq2cUocpX3oc-?UP5mgeG*TNi&X7ur`|<59kMG=ItrksasIyKoK$bbE#%(W5sRzbj@(zHae7?akShI^(PJGsRVh*ic^mmlOYhhK{x8#rTei zi%a7)Ybs7A%*T^KW^rFPzbUQa$sdJrf2E85c$sMvyG+p(OeYrNay>#!x@8m7n_5{Pv%Box)2fZ((?3R@?RGt024w)jsjn@HMnv z3e*10_}y{@EC$)k>!h>25_PT=8k5DdSGEn%U>`O%NLIgMJ=qK*BF`+=7*Gl&{ryRr zfSEEivv4a!@}stPf?f1IK>b(G^IjGqby^TDLn?y)b`^lv=VQIMMDjViaV+F3^VSfL zr#hVD##i3FbFoss5uW#F!uu;cN*ft^MFU_#c7_sRZh`C;fL7g%o=B) z8$;Zg3yI1-d@w44*UVy1){s&iemq}5Jzz0@tk|>eTmDjPFa5%sqkp1wv-%9)MRSVn z{YJhq#V0o>f86T(Q`ObM5n<{MP$lN%>s$MbWo5`e3Qf9a<{!34Ae+0iEp}_XS%Yv^ zI58aFg0#Pe19it&vF6BzJqF;)q;8v|syBn3=y8k8AbHR|{L85zb;+i7$rYZ;-3Na> zH#d?;&&R9ogOnhZ7yrT*M)73Uq5IgeCv|EGCIx83ctp>_rF(m8Ipd)=kGN7qYa!fqZm&+lGVNO0z<9m=EVmrx1<%VeL!aaD+|E}T1|;4>9PW0VXW>|=o}XZr z{#Bh|J1tZ}RK@E15j~u%4RUIK1|(Ob7D-Vri?CCvR9ofO%J`#dO{OOUp4MH4s(GG& zIL$Fdm|(?ON?bT}=drjT?Qi*N&#ft7BB-y8V$V%1Uhj+P=d+A&xeL2}7ALr1GaaLu z-2Y%pF(28z+w^zsuR$1}P=b~~BO_GtO7Xh8k3Kskp!QEtt}b_vfq-u8Z)bnnsa_3# z>47^57jd#K%~#_}i!XMIf8ciLOL!jfvu-v=YN~l4^_Xzt3GVl+SQ=1DuV>n%J3k)O zLJ&N&&tDF2eI4(58Wez>|EY;rK9}V?RlUDR-*5{m?|Nz%Yy;Mj9w>WXu3*LUQD%s% zRM6}~!V0;vb{$R{`*_ko=4El${-d$?cQ}YPQ>Z~yv&NfyNpgJ2MI(H8Xu5G3XOMZ{pV+2DYyrjFCXm!RXm7}sJBrt4CqR}P473sg`H|%$S@f!p<_>Ke zK*pr<-)j!PIVOrV5fF!<*`84#3chXsj%RXV2MWeA89{7Z9V*diZ+1mVLV0SmgSH$K711`xz0&#B{Wh zzMcoYTi{btM?L&gZEGz0Vqmvgvaj3SQLP4OwAi+fWvM}dabL|Tr4JA zZxXL;rG4wH2C}UT+W6~27FO>r@|eRG9njcH$K7_O&_`{bqNR_b%{*4Gv?`?k*Lx9` zzLQrA;pbVScK{U^YM?`5_7UrxfBLl2)2t8J}<7d@%^X`Tfys5!0)WD&EB1J>|j9*6ivym z94aHN-ku9kLnHsr+jX=t z7qWPF$wlDqnAL@hQq^y~NWc1vUo#@x9jfdcoc88pou`*c;|+qHrxtiz96axBD913L z`mzg>Ar+hxHWTNa{k~@FXhq|WC0OHf#vsQBHQkpx#0sUm?0kbP-Wy5rMjzYyb)RJ* zZu{%%#}Hxa3&%~oz3@KwWU*DM>$^)^jvai%9)a#cgo2!gAi;z0E#F3 zYOlR@Yo$5JWPmdmaeT??nlO!%<8OTsZBs!pue-BJw2+V17koBto(uVIL0=)C2Ba8;J?Dzk(q>-o?$J5b&TlGAuYC@d^_m07E%$p(?C$ygXA}+ao5duxgWs40 z#>ZVhDYF{=-`rGB9nkB$p?9J{idy;tZC>gA}^a?0$$Jbao6qQE) z(R2^WP`AYb`HgaKkG!30Rj{flK*{`UC)-9Io=UDWP$>dYdbHKM|wzm3%OX@UuM&O$?G#Hipw+|r_@}1NA>f3 z+;z8xBTlc(?>{b;}N~v+~moi1TG}B_FfueD9na+Mvp9(?z5*XIWMv-J>J(^ zE6=Yf&04u*EUbEK#OE#R$k#!E-~R3KJj0x=UZ1nui#)1#Q-~}Hu>fHAf?RmulJhBh zIFg>X)2%0#in$~a_fo%<%PEa=BbM&#)%GPu!D*;jd}_(NrB|wM3sSDD(QH4t6&k_w{9roP3~re4==4`jr;2 z2$Zh^tL8H^`xNDxu)3iHmQeh=v}3mWNBOa1D{vy4d`BF6u$i34N2`|m;bTTUZcA~Rhp;VyE2HZoCK?h zp(w9xa?e&>%;{jRgcJSrS)3o(bJn#B%a^S9_&v;xnzH7e96tV;7+9RVf*p|DE z8Z2ur6cW(XYPS`XUh#7@``toc$pJc7Tv7}7#Wy-_t|gNds$Egx#)oeQL5 zGTd!LoQfv(bcp+6GhPdAuFCiftfJawfH#Ip7Jk;uQrfN) zy4Ez9A-V^~opd;_i~GNyXisXe-(SG3tMy?u(kj@|rQ&T&mh|?oS${GJ=;Q@G51SBU zkJ9tB_d4k1@P}`Hu8ZIC{7Ia%XVpCF$;q|$4P^Oj)W$iYq{ADyz8x}1v1q-Aec}Ln zvD8^YVSQIU!XMCXq()Y5K4Yyyo^WvoU6-YC9WT@vL`Q_;pD}ZKF~7Z@IAdC6KZ*vn zd8D%;PdOivg^{B!YaAd0zjtUe`&$;RO@qzwAq$NLyt{kP8Wd1RWNiImid#0Wuqv31m8gjMUjM1M2NPsDM>^TD!a0r|2N-%>z`|_m8WNpImSJ@$VT9p z>l+!7B}Pg+dGLRq#k{HTI z<%n6&t5T)Pcc6tovCD&D7nSYHtDB7xla>1>~@G~~Tmh^%rE`Q9m5k4Pw{74NJ!#^v->olO6}(^i%hSL!h=1l&@w#PsO(LmQ~#VlabzXn2L^xbYcmL&jt1^j`j^4S>_$ z`Z+UDA&iSz@w?o8LcTJ|Uk{sU^|NLt1D>hAlK1A1fZzXGf)>X5W8S>mJf`62Ai(HZ z1SFs0bz779Xn}uYZPzYXc9K5~0_Eio6Kb=3UPke0KnD2p52KG2lb;R?El}awqw6vF zNhs_-dVnT_HwO01UdRnyPal$U;L4AFPwE(}?QTMs58Kh;#{320nm&D?X_5y<<+r;K z*|KSOuN+RIGPeW;4#=@<k2_y0b9k%v*t$vns zCGCxJJZ?9g>6Yxp0vIJP@gHbD!{uMc0NzS2335HlhQfyB8qyHu;iJ49x#_%PuGs+u z7FcEt@0VucZD*~37pY+U>|qGWQkC|HAG!>C!II%Lpcb?3wmJUek6F!IwvWKAZ;j=7 zv|9{pL%Lhk^!KjFP!Hpt)t^~jtMs;%F=>?l0(bj8#z67T5Hq<( z)Nnbw7g<}>#FA1&UYPh1;UHNv=N;FF>*z5aQnwO8~qz^%zqJbyH z%ix42(?+CR{*dNDmKVjtY2ZOmj#d@=8g>!swEoGQ+Bd&zwL;>y^4iUo&@(=X z=YJ~*d@V)~y-VnpoEtysfMr_!a=>aO(F4_bV@3<`r7>;2a2w=J5|9!Z=Lr*LAWr}O zB6)EbVp@Lybp&tkkDjVvbhkOcCSyR=B^r{#~n7E)~zM1H{&bN zF6^*s!~W&NkmKD1nh^T=W|#E>dufH}yQ|*yFTmV`(M{O32IM`l<2{m5qiECczQI%L zSew$62;(a73)J_f3(2OfR%t*Jd~0+vAVLQjo|UOsZ9K+Lmw+Hp zlWY|9xqa;ZiFTt)aA>U$&zPFc&wpI-F6+J3_gAT{AEyp;WB2=d&1vXu5&FBm3$&|8 z`M~S$0S(|Z(y?#9%CKA=`!mfZ^J1@h%a9>-IYH&f!`uI@i;rdU-r_aMHNEu_JS5wl z_uUhjzVj;)rfl0}-Q?`yZ+1ASgm&yV)AbO=ukGN*Ou1cPSm#|ZqK{XD+Po(64`T8m z)VVLUZ}+%Nppi-64i}BHacJY}^`mUW^2}JmmS;bo{@o6d?sc?zztFa+8TDFrAduZY zduY7-bfw_gMN3!yGv23c3T@*>*POTbDkR`J@N*VzR=py{CG-^Ka+6|)_3C$g65W3O zwP6`;D#yrC1)GJ9_}L7sw*77$kdQcz6wa;>HU%ZgMB~X6vOIxCAe2^@0~h@vL{gB!^Nz|tX3r!LqRv* z*agBIDVxz;yTXkvW@APl9~H!iJ4Yq%;pJA=w#7pgMm*Bb!mZHvC@%y-YF`Z5Cf|`Qze5?+pc>-#9-SNw?a(eqZJ%8Kz z;_o8G&18IqR1Dsrlqp1bcAu9pAh~ym+tfUmEXI>`j$Yw-j*wzSMeNntVT-tS@D`eg zQKmM1+?DU96jz_C#h?Yq?azMheCp5uKZBIot=*-vr{AVq+!ha)6@N|}d;MhIPNnna z4|^}d$$1MCpD--%1(x5P@f?%}kmFLcy0_>43Y!b?P;k*-huf8d+SC?))Q>q z<*Df_v%G1#ikZk`Leg?{`|mN=*0B71hNqDkaq(otvbg_ZvY<<}**z9ou^< zxkxUBtECN zp(FJ^?di1jT@T9nhyK>a-F}a=t`9C-^_aiMPAN3;ol#AP6KoE;h|lIq5Hst-9M&m2 zmtS7QmfxKQ1!&FXWN zz1Wi4QwZLn2N$l-xC~-7j?Z zRj-U2rIOV94(^1mFu&sHxBRV`M;9(m4pi2?3If^$oO+A&3E!-(U(l?OuAp{%Hia|U z%ccEVx3b6|?w1+k9n<_u!|x}z9vsuIEn}x4A?uAn)NbQ|aBg0l_FnYmJ3o7jmd&wv zF!sOCRI}c@bVF!6B^ecs{^6@SPu0wtb;i-cYt z+jvqSAfJc9{4y?Ywi%b^KY!zAYj8#}K*hjsKKy%8z67$fo%Z@MKw75qM)?ccl^x;W z(Vs=1sVq12E=54Xc=LN6{{e>g!m+;#^=a+zqrY&i%2zmOH6{jkx}0Yym`HVwJB_?& zbKh?+`=@JN%WNvlv`CyJ{*IfpNhpqaXXT`EZLdH9oA$5MeBko)njns-dvi{JaPRoy zsGoq#tOR(e&aArG&hkOFreUre`wGMQJ(a2!STvV|%a49V=9isc1q4?m`OD))`ua#W zi1F>_ht*vPTLDCC#8F<{OO%E1H1?lKP;J#lu7U3lm*XEU`j18HwI0OmWLa#fXHc#- z_A*}YZcVJk1B*Qx6}50%@62p=$T3G~I+cV5Ri6tDx3jMDY)%pNJhf|&_r)U|ucMtJ zI_BgMB5_*<2SI2rd=qV);G4Tc^EFo(lM; zt#|lgEmOvBFmKf7v)e%|udrJ@#L3;jCDuK;Cwb>gNT9;V82`11fGRA9-RS~bvg6** z&rxQTj343@_Q+(Z`*dfoPqzimNIAl~@v$1_*?Slu82^GA$KRP6+a2;=$T2TI?roj- zu%SnK;qJE}@Il;20nlk&Oeyaap6zOxed_kUV>#-b^xI?J_`Ab7c6*=3j9Opc@A4rJ z&+n5Ezq}jRxU*8r!QLEC+uA2+=<8hzs^TG#N0(R8RB+kFeI*@r9YVBlSP#rqH@S4C zL*zENv^u5H?^QFVdnzwcd|G~7k;P>9Z?0Z?aM(ud4m~Bb<>jMIG$hwnXPxIK7shE!ZS> zbAAu8$UT0mUzV$6T42gC!Fc!SXTKyDxwwvq#SZj*^hObS1;PC5hZ@gM(PnZ!dyndF z{eF!4t8;bOzKj~bOIYFD*zYYVR1se9f9M!0fdFz=F4ws zBcRq79la;;j9t=nYPIV9&mGB4JY!z0ri9f1zv`_fUgyT1dk1oKFD)KLYxW$Poo6=g zMo@?Pk}-#D%*DM2L6!#iLTVPdW|Js-R!)<`v(TIu0o#0u&BYJ0qTWJpd`6Ej2Qajm z-5kD4$h19uD78`DW|BQG21J(v$O_yF=-F*$g?afVf3$Pm+`7dwSHmh&He&diK~zFz zk^jy7;Q`s>)bO)q3yQKUoo&!A3Kb_BTYUjWPYYP#YpyyQ@W*_ce$m2(zASIxvl*Qw zf}2>M$!K!@5$^=)7aXFCjN6`XyAy2Hskp-fbg_YD4kUFDVnwHgj&e`x71vin=LDOP zhV>nvC;38;IL(gFEwbP~HSgLhCBOHzUo-x+WZzTWW@V4O{7mbYH#f75Jjxed>OseH511t(;^{!X=CGp@NaB$!@#@SFW&`tiId1Dd?J+xnlFEL!D_ z83MjG_WC#Tf=?k0A>(yMZ$lwx&rds5seGF5?e{?Hu8_ZP*r!@-$5}V2FD*#p254D3 zuY*OGdePzQpej_<$7Ig@Jc7`C@2-~Y^?`3J(C@t9_O;@k*LxnMM_2hDM=N)5XUh(VE7U6M~9n8hakpSWnvF{IH>N4R0rPoB$6w}7@^4j1 zg{fJ*E(~-R;XE||h+XsQn`+s{)>2M+gDts5H7V}U`abJzWxI|4u=0l+zsa%)cHb*( zMXNukN6y(laqBCSb#3uF?W*`a1(S$XQpp0**^hqmehv0M=!3ctF@dt>d!lBWj+J{N zCV>3)g~jxKx&!3U0vLx2l>vWU`}K3ZOq1Wn9f31BkHqlJ?jWU`P)n;$bygtnR>x}f zWGFX{utmMm9Ci$|u(RJ15mlx1y59a(Hi5veeK{;YscLPTi+F$2 z3%j%F-)S1}-!4O?)S#`(&R0ro^Na0-y_$v@4)uWN?RBEtQ6O} zHm?Qzlo@6A`~fwad2;XIYId2@mA){ljTHtaZL2Jx1re8nT-Lw+0;5+}s!J+Ysic2L zcT>LgdbIiZ{VeUZp0ryfO6beayj45H&>bx{471(- z+wiLObgB{ubL*sV|1CV$ z%{|v{{odz}jS1*2tqh7}{41>gZFyJ$;M}!9{7v2Y7B3Tod4;HeSqyg29=5I3TwR|| z9W}mah6+zI zT-18!OHorKs~&%{N=6l?)e*IB3CLyJzj02l5|a&~?*CII`2n=tI&npeS7m!>qJSIgmt?cy++GNzgj7&8M9Ns znqIcWm(}-3Pa;5<9$d@BsM{%w1MA4THjL%hBeKidOA6s^xP3${NI znCP1Th{*u@IGdWDW4{m-JRG}B#PX{wd4h}MU!+Y`NAR9|;KG#Pk z|L`k~J639}+5Qc7|KNVO?LOnH;sxTY(@t<`o$2{@Cwetj>D(l~#u>rTN%q-f=YKtk z?QfNT1@0e|Y0%uI!2AJ+_EL~wZAg|4{AqT));5~y+00vF;!zS>wPoYMRJGR*p|C#7 z_@0+1Js{LB4F{UacMhK!-^(71Ix|P;y*t(Z7tXO}87H9-;r?{-L#1S>8NV{PW%ai( zJ63<;xYMX?p1*#^^t$aPpu9GD@=&d;Qc5s%7Z_p{rq%C zUU+%dtJhNc*om;OtmL~R;qk6YFW6sQFK$IC=NEfR?uXd-4b!U_^P919))viM zr(G!0Yyh&-u)TQR*;4zfWw&)$oTkyeH~Zt*jWJv+((g#r3xRWLJ-Q2pSfP!tySsn*?yPe(S7E=aR_O0YQFXCfSsH#Ku_-=Fpsu)Wz|JP%RTJE0)v;3ddf37A zdc2o8G%Eix7x;P~;P5@%+%EXZIZ~Ad=B1^ohr;5ETAcZn4JY~qM zHC#t(I_TvT?6%Esb>DOMyKa6AeoJh8=S!c3;Z+zo(xTgfo*S=Y$?CxD!{bqlJ)dsF z$E4CN#pW0hL+kfmedYSwNw@AeoBKq587CI2wdaZ9JdFBMI`7pfQeug=4$Fz@wn zd)<@$r2J%yMBMJRdzCZ+S0nUvlm=r{T_%YXP~i<+H&zE%@XP5DRA!7UU0;y;Qj>Kp zK2v4=2XvHPXc2*N?HpgZg*3HhTs@~jVX98g1V@hgk5;?ApC6C8dN-*Ywb=a$d~L{R zUrV>>iAEUne|mDQK(D<`+9vxX)M+X5kzbU6JrYxkUE8vPDk--sH@os@0fJoBFQ$#& zn}r!VKG3G(@ni_NfP{THz%!T_jPfxODh^nbR%u6QBl_JVNDT}F8`KP_} zm1$`kwTx8xe2dtvD6aNSgl>hDs5qwt+co>Zf?1wZSR}dRUpx49CzW0>Eo-S}UBH^Q zAa)1dcuw0p2-lf9TKH?BhY#$;8Eh&s9s4vYzQN3g)uF>?ahM`-=ii^w5RIgEsZLVl z1#<_%)-e3dZ;kWP{V=FI_uYA>?BCsR;bFEuElEUao8N3aNd<+~HZFzUs%_KPe=g{t z{XyG-3?X6m9zTvLF;v>x8^EJmQ(0TK*1}5l<=$bJmoW+;4MYpfx{nm6wFu)2dSNTv zjk+E2eSMNe`R<1vyF=&p>51Rg?3Lf~JHCv-PJDFco#5C`ov5(+PAxKOwgxY1+3rC# z&d|cb{_)lym1Y=HyM?b{^x3+M?kmXSqOkX4EqXs|?l1jA=2TA{?FOm6^cPE@E#}Qj zH$JR4y@qDO?_z}F%!|h9tauLFt-gg@?tO|Ra8tRed2+E@Rwudpx6;KM3LKZ8Ba>Tj zq3ay>^+U}LPxN0ighq|lfXB8Uzn&jz-`o5<&CLGQ8F#3+RsN$v9bM_gdR9hf-DfqA z50Gj;TV;*v>_+B3S~*8fS2wey8IWfMj)Y+Qxp)LE*{I3}qj_U3i3TKN6=b`}KJ82A zempa|bh6geznsol`IcPWQ``vtV#!hmA6iK+itQ?VtxIwa7Y4J_^yRWDo`bTnLBC7G zRhS(#ocjbk3NW(|R&q9*QYr8YYnR9eNtz5EpQneBTG)tD>)Y-$4Dh-;L z0~>j8@oxZAg2v51*WZk+X3Kq@>82**wd^&HAum?ktCWZG1B0GZry+PwsvBX?{BB_pkip9=*$9AC!zgiMWnr#lfD? zdn&_&VK!8_^}YAmg@YdZC)BSNMpqkZyvqw2KV$Q}$9vHX%ZvV?Sopjk)>Q7um0mk( z?PcQBaqg;d{|SFftLgnxg$W|n!wz&_?n~K`@9IswdSASe(=~$=M&?eBR@Hf$KdE!` zZ!4el&KyB}=|S~aqvlg!!Xu-*x-aC|#l`XURg`m3(qT~;6cN6ZH+LpD4qPAv)k z$@6_dX&)7P@>*$AhJ8oT4!qV}{0uNX`u2Jsx8~HKJd@wg%6V;5BayiZ{pPuz11&<; zHB-yJ3+Tvo^X1B6APnVBK_9KBm7ROHy1O|6umHJc?#1f4y=kD@gsJ#>Od4SK1L!bV zHGpcHh)5oVr5T@Vck`5ko6!7BUYAWC zM$N`wZGM1ug(fRLV})%{@K_cn!dM!Xj?d1`gw4BQ2GAD%_vbHAB51qQ#|buUJN?^7 z4xpS=r0%C!HlU-K&Rw}g=-#TM3mL`b^-*}xbL&aa*m6fNQ+XI6=*mdo!w1sEcZkh7 z|0&!%TUqz3)w2e>_E+|SB)qJvcU1IJx4 z`m-BmPihOPZK`4aQ-b1Tpr(8&92P3A`pJ_S9!2g8sS*S7OZ zQgI2kc41)(R&hhIkfb%qF?YJrtNg3jf4|$sKCr>5(m}K3$+OYg?5cyb56-hA%yjRu z%DoEMuwO>sVI56p=gFi`l<+<5EP&mXulwz?TiJ%w&Sa5S%u3I%0YrzrJ#1Gya$Qwo z0ff|12@$!U%4}0ALS(D_gBOzY-8lLVLl$2JAV(2PW}p zj;F}O+#vekR!ok)LTOWMuUbR{$p5V^p6EY^GENyE{LPzOF6i^+NsL`56!rYR{G5Rb zOry&YK(?P>nj`Shg+`tJj)sx2DQwQ)@LYQ4C~!mlt-D#V54~p{RgTZNHqnuTn44$D z8xSqV#XmOyzCORBlG4#KSVOW-;K2`RnK)TtqdLWew1H@acn@VYw?1RZ=&4#atl$!l zyem7Tkqq|xqmL)u_`XjU?;$jd5BJ2Yp~mtj0!Im{Kl-ObTzV|8Y+&aTRbJ6=U~aaL z;-shmJZZ+hbRojcMq!2JFcz7KT*m|yShA`On{WOFh2j`MP{7e`Ocuq$^HYx|HXZiS zY;}UyXj~)UTRjSwulnJE3%zD=9M%jmHs1E>xvw|x+Ht{ko8M`(*s6U@nt9HnJ4IJX zeb9v~dB^zU8ij#0t2VB533Qmu>;JWMrrEq7_c#=GoCtdRXdb(j(*=!6Swgs*Q<876 zlzDQ$HxYWktVizIdPKv=`V13vTx-9F#fCw@z)PxVmUm60Py4(wnk66wEsL|z0Aiau z?|jE2b3QNab%qFezw8{9et$qLE{PGJem5E(p2ZV;omSpCU*S>co3;Aaku7uTf|+Up z&_xo!x%T<-ia*}GTE~EROwGubHm4PwN~mikuz3fMTXzws{nl|T{BE~niE|6XmST^U zeV-$7qnNu5xbALv9{vG9bzzMcW3Z^r{p+w1kBC(bmOw#IgLv7#{4-0NwwDZMn?z3N+n@=cu``+MaKontXx<}$TZXsePzkYcS z@_RB({SmhgADIlq=czl1N-N@5%CHeW*PCubSOIU-ynjBgyTsD)-@gDobi&F?<{zKu z8)B6UtKuDs8pn8lygf0U~dmZhjinp?Z=9 zbLqF#v)0YO6xy<$!A33!)$8#lZlt~NDXHwZzJoqARuPI;vH4rvPx&$sk7e&3NORnE z($jW0d>wOJVFZ)_pjN*x!X6F?r%{c|Dij_dfC$C4)%Xu~qVD_$9-#O3a#E^dr9W8t zUU(X7%u^At@sX!*<%ay13u-QAoXUTf)j9IV#mK4m`%PPIV-lgO@F`y9R0$VLv&x@w zE8@qGA_aKZnc7MqA4i2oYmgdiGr3R8#xU2GC)8I(U^{bu#=T{GHqrWRba;3W)8=1w z>MSa%`%1_B@|znE+o$|ZMV-M7?#Y_?LmuK~+iBi(wAPJ)l$Q?aclTv!cVl+z#7y87 z^H@-+;q%eH`)Id)v2foZ^7o!c@IBo!a9wY4EaxBGL6*7KdRM+0@oTEA3N-sTj@^HE z%Tg=ANT~W_h;gCk-UfELq;7`;;(cUCxyIb`f=7Pssuj8DR3~C}w#)i5TjH*6>GLCo=AT;{!yN{pAQ9u_#V z;tn9__pVdw>M;zENj4F`$su2Asp7V@7FE@JQ^T3c_bzktx19%Ioe(@8PmB(lG>Bk! z?C46lX!ih~KRG}eJr_KON@=0I9r`e#NIf;J^A#RJa{Jlw^ExGY#oS77)(*x(w0FhJ zS7(pQL1_>JKR34CY-1`v_lGIGHBhxaEJDV;)|&8W#Y7 zR?cT@3<_xFuoyb?K68Qzko(MtgzU9*qHydrwzUb|Vb*i~zMSrsB`dY~LN`~*v*I*& z;{E!;WixVN6YzNFpqS{~7OC1!k5F*y_jK#ZPNi0DauAwEud#I+i}o_HUzE z5U+)AS{^}v%yT_z4gg(;Z2vAAP@9ZY+I)=-BF+Xo;ry$VFNdzT~>jkK{pL@Ij%XpZz6qu8(xf-mY;ZsYz*-HG(+R&Mo5 z-TA9sc)GlJKp>};efPf=IcN(dST6nMzw4&aP>wlp5l~OZoL0HlQmkXh60E^2X$MPo zR($T5(0zBAu*u<7MF{uInO)N=`{!5SUfh#@&fMTlE9L-MJ z($AxKOTg6QvDG#nEZyjCt`wTAK(%g+rhh;&mC05w;_}Dq$LTG)9@7QRd|$~8lwSAh ze+{p^I-frys;P)$x3?R%WOY!{>%e^-UvA@TZ#wBTde1>q^s+yn^PH~HZ`FO}w2i|x z2KTXQjr@o%LH97)++1oOygoy#y1=`WS$qH6Lm!G*p0e|NKUszGhML#FN_)n-!s1m2 zov@OPiRH6YU5BfmU*SLC1}4Q=)R+c8?#H7yk9Jv>M&dzyzOb?j(e?}i~POgV{s)`h`EKVwN7CktdR4zLr(5B z-`oxp=j{?q4N}*t*2T|*A#X5htJA)4FQD9ikFDu#ZCjr&_FSj=r_Z&)KK$$0eXO_3KK|blLL>rEOnj~9 z=HHGVl^d-Hn^O60<>;aEt9KDzJMIeFMVk=3ed}w^JET8CzfEXIm)DEmu{NsKdr+7S z1TuxZQq3;F8)tpI~9X-xr5y^Z5LPQVO+Sa z*Mkqt`)mYonjHFYDQ<8S>NB;I@YwCv9(xVod!y#{9hJoMb~hU(s}bah_4uQ!@OH~8 z}}`CSY<)a%Jy zedt@&F13;EoccsnCD|jQ8Z$c)z$0B4$eS~Mq7-}bi~gnc%S?{d;<2BMp11eU3|Do< z14}NKX*IKQ68pt9YK~ODAy>;^~X7m$QrHB*AS|h}I{RkHl|#tH9c)nx%Sop#R~_?VeJ|;mhn#7?j7V~bTZNVDL3NGl=+4(ZY&3MPZRR^zM*Th2!)i2p zW$SXAmv%-s_t1*eEz4+i9*A*%+pn2!dVJ)Mw=Y-}fZmXH^z5@+1uy9yf5zGRxrox+ zpZ$7xPFgkg^aE0$L=gkIn093brx(}`)CI3 zg6L>4c{iv%HeHv|3HXygP?WR0_=n|-$fJ`uwccwG^fzSneqO#Z_HbT!tJmWuIn^O; z4%^<2?kqZ&@mDuqi_S1P?4c~HOAVmYdm4+Vwsbka1h{W@{%s=Pf`|7`Fux3P5n6^{ z;q+U4TF3O!%oB^l`}r$opR%*qpP+BXGsco8>8-K4Fr?~6BO))K=xD=OE= zW+ue4}?rYFUfkpbDm+eof4ydLhWDk)= zeU~>FVX^F0KIs(=^Kc)lNyw(|44%H}fHF1lOh?#lzdhsJ6#`To?C0GIq_Dd${8E@q zb;bs&uDG7~;s+GMEX`Xbwq68Y{HbR%zx*%Cd4Z{@o>5cj>u zOgK$?Qxws-BlF!c{yj_NUv9D`$zJoY!e>uCJ#yM-ahqX2|2oCe5ZsXO)&Pp3qsf}s zN>z-T-^6qp4njpJSxNBvSY0?2+SmlVqt9Z4t0)!4ryuG|XZZE~NuIBbR$*{0P)qS5 zOXj0;+ko=9DXGxPTLe(RNhJbxa<6zu2Lf}$fzDk9-Q~tB>~15zI@Quocid5)zG$Gx zyBEMc`Pe3g(3DiX^?PEHKTe*|?eenXTZ!_tq%9S3gu>)-4;Z#;$ay>Ji`l3%vrFvI$;$mWBTI(JUk6?f^I))m=c zyKe|@@xZ)O9z~1*Hp-iB^8|O%HhBO3m4NMAgMEUk#PD&~of+8C=}gPuH#0`2mAfpY=PRt*a*&_)UAmlbV|9<_tS+-JBCxBE@!leRyL?*0WU*#-oyY3Fv{hz zkNdZF?!g#YNJrPex}w30eG=$izh2$@VAqC1O}SAxK#KFZ=}`kFnhm1x3RMyWR_}M# zCw_RkcbEEmM^DH7Fj)81#!13njU=PnZXy?3&)m~ew7jMMo*`mCllh3}pjd*=?O_A| zH@>d3C6}%??+d{d!4ES99I?T@W`$DYa8qV?TN9`7DLD}4q?%aJk_03^FE9qXCK_-sNmC{_PJ}jNAJMQ104SQv&F%%#<@YS z_yEq!KMK((S?B0E);e@y?dxvm<=6hCXw#aZE*VFGi;-fk7$Ijkwts^1sIle5dxq0r>K6vlOV!y9%(bCsWPsUj8Frk>2j`T>B#v<3bM6 z=VPMQURZDxd%a<4|0T`hgF?LUu;aG{Q^E^FcDX8|ppSKiJf;JsY(R@XHmNDd?M0Hm z#ieYq?lzaB`1;9WudVM=x9wrtQHSmKC?29$ysc|_&PUeO3Ug{dhxIcW@%n*@sdb6d zAFT&->I`T+J7N-eN9RAL$O-7~onKz%S!pzfCWO{l0WiUVT1-mrtQ{V1aD8w~>twB6 z?BKof=QwhMSV&3@M+)&&%=K~Sc^w|h20|xy<{G+xhdS4cf1#}_K(4{vF%As;$9uh? zKK1@wX?z>bc=Px5P|7M4md2ZVxs}IBx$cy{{JQ2=tFBNuZW!)-`

CDh+r-qSNb& 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%0A}Gg;P@rr4L5`1Bx|||D_;xf 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

0uU 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 literal 0 HcmV?d00001 diff --git a/ahk-frontend/brand/BME-AUT logo english/BME_AUT_logo_COLOR-eng.png b/ahk-frontend/brand/BME-AUT logo english/BME_AUT_logo_COLOR-eng.png new file mode 100644 index 0000000000000000000000000000000000000000..4920b4b1d106fd8085234d5fe4d98df0b076c0aa GIT binary patch literal 56097 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 literal 0 HcmV?d00001 diff --git a/ahk-frontend/brand/BME-AUT logo english/BME_AUT_logo_COLOR_CMYK-eng.eps b/ahk-frontend/brand/BME-AUT logo english/BME_AUT_logo_COLOR_CMYK-eng.eps new file mode 100644 index 0000000000000000000000000000000000000000..1741be870f305d2c50664a5f36cc29806246888d GIT binary patch literal 488550 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

`H(XVxr@AeOPRQ3fM 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

@PLrun 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

6>oP)aK#%?+WTS=g(y#m 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

Ng06P+t^Fyg(GQZCg&`q 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 N*HUCuM^nK3{U1j9D7ydv literal 0 HcmV?d00001 diff --git a/ahk-frontend/brand/BME-AUT logo english/BME_AUT_logo_WHITE-eng.png b/ahk-frontend/brand/BME-AUT logo english/BME_AUT_logo_WHITE-eng.png new file mode 100644 index 0000000000000000000000000000000000000000..21e62ab169695dca9b6e6e38854134c62c15c4eb GIT binary patch literal 54159 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%0A3g@!J-nxpNk%N!wz3153 zhH;^UoV~520D0Ltbwnfh01xVXmYqh`n99!6&#}`UhAb|vf*%vyR{zJfzVD~s7QBE} zFWtZd6v_dpU8uGIKmPLN?A}Z-#k1$uv_PS5!)KrU?_>Ahc_#Vn%f7-MIPe{Ipz$Pj zKa~U2!TS&S82KD@=+5lEIX63a|1Ng#ZC_@}EB9u1ACn}X1FWO$?t5QhGKv{K@?XCz za8|LJ$D4%E3M!G1rabo7?EbAG3S)SopWX9LCo`UO3A^Wp(Iu=BsGnZ`))F4P_!#@? z^T$(|J@1mSyAPKODMc9kIBs03e(`Lpzzal*fmMRGpc)eU3oas72`&#%Nrwv%=>qaP z2MWLCxUmMm{QDn;Fu+|@Z?a$Bcrv5~wz6OTNhXxuU+r|j67q8W;EQR&1-QqRe_#*Y zbQ*>E*!Qkt4_odKq;38EcOOdigWqXuwrTLY%nd?3FO~jl3AqL@3>_@E z0QcO-%wB9mtGx4F&$1V@w+qsKo1K*4`ZWtJ(l>u{flwlW`+WX&_RY8MC2617dM&#+ z^Q=&_;3Ln+**6qlBcD&Ju4Nb8s1VA*h1VFDke872FMUC90jmGp&45+xQ{~gy`88Vh zNy<66?Dn{qUGRg)$!EWhzsA1NE*CVo=(_L{GPb_mp!Lnvu8Fw!_ZhqS6Ogvg9XGLC zUOQ5-&TU`%#1eA5-H_yM6>y)C_t=fLEfnVCC*|3VTY3a(H)e*Hkg<;lHeCH5Z^@sv zO$fZePh=ivz$$jwyLN#>{eg>!+&Yi%cf8;N)Q)M{lOH>W!f4L&v!}lFGoh_|y7trT zfV1~yPk-w!=(hEE1{b7MiW^x6HEEYRrBI`Q`z0FK&i(h0w1bSdvycAmlR~{g?~nQe zbLE`$N@ch{{9NPX5D`>^v4 z_%zc|KL?kF6X)31f9@wA^?`AAQJ|K!P9)(*oo9ED&%t~Cjosd`uMiKy zAU@z`)_F?(CxI6T>j1fRK*2gv308|R!NgaJYWAlCpC zG>{_K;FT}@Rqz2q10dG`6f}?`V;^6)J%D`2m-Z2)0b8!Ti8*#gEg7l#7PED~$d1~- zn>EMxV&A%bh*|1#%2Qa>Pvb-pd#}k0&sFTmLw6CVt0*3Dh*%|1y*DJ6 z5S)0fVh9Zi(xkXi&jj8v|HDEUU~K+D;kk<4lasORE+?@!NP`h7-y&8CROr>?mhiXV zxPV1386XXw{oZM8aK4TGd|Q~CgWqAv7cM8COaFc%!_4ax@&RV=xkkV$*1q!{0tHQ^ zbF|IuCY|A7{($EyRzG{bKsl%!z(vF=fjaW_GnNpXc;>SYP|!e%n`s~&(H+p_XL#nT z5uh+)kRr7^p{UjOvzJCs5?b;XQyojl z+xX}E|01{m4?TGcd+z?9Q5e-zm$DZ>_8hCGRt$5D!@l3de)kiMs}B9lO9BP0;RCH- ze8IL&>lb!DThJQPU~}L`xs4pdtV2ZW&0E~l=_)Q@mDe_#niuw>}0IdC*S->i$ zI5E$zDqJT>``#V{OUT&HR2J6y@fv(>*Tn)a@Q}0KW7q!0K^h!({uXxKBQG*JjfgQu z(tpRyZg{GjeB_T?*>!h2n3gp7vG-@J&UFO)(ZvUmk4FAo_T$~sx5G5I#U~0(rRx1r4OQkp_qnE88MM8lHJPpwL=Mk+-8&AMX`>fQECv%6542 zdlW`>dx%vv9Uw@P&R{pw04+H*0HQYoa*Kk3PEzEx9wSHi0MVuZd2a>^(xkYV256NL z1_)_yyzwSU)6#Cko84i-)^A?;gC*qFdG)wM1s5PVUp3saP3u>FH6lpE*b-8K8)<-a z9Q55?g!BOQ=PQM0ngde#f(vp%iaZxEuZIs1oWLp}G$=@w;$|A0KD8i(0itvPc|4#{ z;-$!IBUWbN1B50(ZXHn2K#Ch_fEcm*DI(H?XFjR{1^H6sx?%1DA0S3GKyEiskS4{= zG?1i^02DNk;$|91%NeAh{P9%+lu6hcWmH6-3+Tb& z0>pX(klPIuG?3y(8Xz6mwGy$p>kYP(6YX33{-0+%zI-X`qA>;5o`lJvu*58mW;AR@^HRcz1fgSyOu)XTeCuzO2x3E1f$*}<%HKAsSSS3)< z1unqez9-pkWjBTCXwtIXt3D%0!zvpz0B)wi{0vldry^?a5D`)ed+T8FR*j+X!hy( zJZ$i%KeGd#;VJ&qma>pyAa}toA8Y{Z{bG^r`_}^bv_JeSw*TdK2-3idbOARSD}x7X zbs}0wDxP_X2h~RNZD64KO?KGGH{f&nBs=t)^M!IyeeZ3|cj`Gz{_%au$9=@ptmd2J zf^Jx8gpPa-5)@J>BDDVWfy!-KAN14D2^vV(6*sdRR&k&;5Va9l#jxTB3iVWqJUwWm z-~$9Fkk@)pkS4{=G?2EE(15q2kP8a&NReysv#a(Me1PBtat%O111WB%0s3o%0YU>H zw*e?IQ)5%1`QHlJyeJX zKF|QjHNeUOT!4LF`i+28dT)PApdbxCB5pKV2T$$`?+LuXzF!nse&1&(o}-K3V>2{n z!I}{8>LU*mu!`M(zFMHLUIiZ!`Fhpl>`8(P@ZKxG!+=%nyXUI}>J;i_;Bu^UcAL+P z^#nF$+l{426Zk|QD6s6+*c}U9R?X7894hFRp?x#x3f#=1(lw19)m!YC9;^U{Xov8a z-Ty4u?TaJ>_5*T@mT#I7T!64BkXsa#gZQMlkp}2pKGs$gS{I-{u?O4ryt7GK|0i~5 zyG&mq#Do3^8t}awQ22=$qPaSLyuAh`_L?GYv__23SbG%l#3R2hJXf)wHq0>l7xxhI z$9>f&myqWi!XPh!zxc|I%n9E5nI|Z;}?k;~rWRuu53@gA3x3;zs2SDKs7S z6CtI*;^~Jo!|yPP{%Z0arvKE7LOeK~apg1bGR^LXkk56y(y5VWCfOY?-N;mLUdSG- z+l49bdy0G>ADw0jGuOW6=~_X1Aa_BlkMsb4aipA8AB0u5A0OSuYL1-~;!)7f&{w|x zG*hK8mnnX=gK62Df^O0}zEN%?JrUZ87O_n251y;o>0}j9S5b+VB43>hzL*kxfEQ)^ zSpSJJ3N!m(8KLGvnzW8@rojsXCYQgGJe^WVRpopo}Fd`h*) zvorVaXP;Nz%eItnW=Ed+eRjtFI`TQ{TAx6Df$RpKqp3EYDgPq*e34q9Gq-lKW5}|Q z_GRUX?Cd{WM?PP@^?R*M!5hU#4KWtT0XuH_!;V>K%w49k=EA9 z1-ow|f)meG452|mniMz7g$usBs}Kg54j;{cRcx~SIJ@A~y@gzW%i?d2VHdm&pVIeL z?81YdWS?yc2s@FVee!;G(XQwLKX;6eU6lI0kUv;|`~1_lvu_@Zncf!`ZW5?tX~qhl zuYStRzIos^JB>;g*6PkV+0VZ7#_!1I)Lfc<@90oaP@glNybLLS$OU`HB7&3W96}@KAPu=7 z;znf$JeN{iDB_WO{)t`DeGD|9(@dAv?8QD$d5V?O<3_*CzIDn$zcHwzZU z>f~vu+t}r=JV8FkZ>bShG*2O^SlK*l&Lbez#xL*BE+e1{{{JMx$P8o(TTgU6KPfD8@C+6zHowpeQT(T ze7<<`DS{NF2hv2`sO*5}hs}cmFYpUzKF@x<2j(S-jE z0b`_dc07#11zJmyrw6O7@ByCvrI!V)V#nP2W%m7>_7$YTr(An0``(MML+fum%C5|Q zT+jd|5gGwE>QBLgbwm+A`(B9Mc=ui;t@J3ZIjXM{>NeIzkMr%uu6yP%@+m)iKl|}x z?+A4bK3{q;Oy_DQ$ma{~i|nTN=pZfi3peGy$WH1qvzy%CBcIb^Z?NkgeO{=iScgTu z1@eCG+OCTQ7vOQ9FESw2x%c|nkM5Wibi=AHbOdge3z)-z7kKoUN3z@gcm+v2{Id#n zSG-=_KErN1VMfs4)+66oLarNDnxQT5RP&G64cTic%!!vj z!ESN(3#AvUpojm>$8NdjljL*cnZ4|$9nTOnfDNDtaI+eWc@KDjMOqUAQZ7(!1ch;d z6e$;4yC?3Y%{0J{2EqU_wgB>YK%qsFB5$kE;=u>F<${l}YrgYy3iB1y1HyS4NW-}r5jWES z^#!~@IpWhwNp}BNcn^rx71*4wyMV%pUlEZD_tayB7P)}4 zxsWEs%{0J?T!aB0w^h6CtnS$_m)JwiB_SU8AU+^32S0y&f58O^4Ic1*ZJP#IRe>}q zZlnS760MhrU%Bfvc4y{Al6La>KV^5`8WwDglS;5TkmmwwJ6wP#pY&CB`!$#cf93l3 z*zH3eK^po6NCj@B0mh-&ixBaQsn4?0&qLpMuKoM$bo(VjN-_3_4S?JRm?yvmcn+PS z0dn0yi8BciH`4%Pe((ZMr*r)0f9qkAcIE?LXBWQu6(JssZV?|J_kzM1KoQS9YlfZu zcRz(WXTF}DMP~sZ4f7unH_~8bN#BxrVq0A}i_STr4j_e6q;Oaqh^gaJYZkZS-6 z@ko(tfHn#~KxhEu8i0Z{DQ>0#dVhogLIWVz02JbpBG&-*2R=Y(0OT5gf;1^^q`_6x zlS@}2ZurbKEZX@;l6LFEy{!LBN3gr7r@)$nh*bjRqc#dIz?fBm6H(xJ-1;WFvph!eJmfr|{bavW z*<&;wz3W@|u@{b_w-)xQBA?&x{0xo$9%1iolPY4B;DWq_3-ATnDF#-tUwr8~fr18b z5pg5Cf#bGPq`_@uRkUIvK1^pC@k}~WC{p?8*c01)?v4D3J#swO0)F277xv5AuL~OB>=!fwZnO>y zokOAZxfI>V{?1?#@2u14ZIkC ziU=F}rbV$vsXHsHbRT51$uq-<91L!y5jRcRa>^K5ApX zqc9lvzV^3^*u6*IO+GK4`4s!vpY7~*(i&sfxAz)m_f^-E&#R$Z*#rJPgxUyAP%DAF zo}y2L3-Dc9rT*#rVe%?tJ1v_VP6aVNCh# zg?F&KuD}~RFMe@XcK68-3n_&(q!_qa{$OkjUf{EI4wsLWU!y%RP|!_^Tx*Px;R6IG zkWT(mXi$(Q#f?_xz>BjaB5tKUkY``PcoZkUe|_$&>=CMSzj1$`J$=i^+4JvX)$ox6 z_G8cOYGuEsv_0qlC3|V;T=v|tS@QY)ji(AO&<#E!a;={@=zD?-@U5VdJ$~npD9j(t zTi6roW7%6I4Q=l$nO)ga^E*J=H&0>DyfMaJA!&Hi>35&(U{95QOg=B?d)O1V{gJ&$ zx2C`gmyW*T4)h%i9N0PG@Z#XJ>EO>mi+0~t?XM{ zw+JyKJxeYKffeR3t0D1m^f;1^^ zrU6zZ5eA4d3gjsTg?OaMHNbuue1OmZ$Ta{3X;R!w1DtV37$C~%Ra@9t8+gqvxAaT_!MKKZlnvK!uLCJml?^|$P% z+xHW8*fGw=PCJnAy<@KkE;OatjD6U4{Qp&(_TkWwjf8{o_re1PBt za@{~d11WB%0qPIJ0AT|lw*e^VBt;$%Y9V}pumOMtV*DIe%LIcz}fv`2ZcfCu0!7uq;;Nk%o1*<0ahWP0q_sA7i?Rnz`PMI zNU0RL4KQbh4-lNZRsI9*isJ1dv4n`YnFd(B0WT1F3ak=z0R*+Cg87Ju&>GJ) zr=`%+84IN1c@qr;YZ9-3BuzkJ?krH0(q+hPfOZ--0Kx`;zaX|v>%Y6+7Se-JG&BHi zqyf@_7FGpK~R~P+yzzGS_7a3JS(2kN+{E zprGrfpt#U^i3WHw*kh^u7IeZ~G>|qu*Yc zf})o4$v+y;{inBPu|Bi1)A!yDm7Roo-}jei`=^*+_u`M|Hcga+Z2rxZJ#25ADHYfr z7prGp&M#J1WLsv7|0&0npxWO0gyK$xi)i`KWc6c8{!5f{ZjpfS|380Y@(pNNA_`9? zIG&;P&M^P`t^~d08dge~x)Thuq|xyB-{(W!0?K?0#0Jo{EC2h<%l(EGb9D2|e<&n= z!GtLPeg0^C*6oae8A8?Ej1GaJ>pxwjFpW`T4e3=>`R~1UhU`d;be=_I6ompsSOH1e zmg>KMeDj1a;6I|hw5TcKL}+H*jy-w<&R{y`n(7v${GlcKD^Z!Z=-u-z|NHvxxQ~C( z9`uDSMSJv!COE?>jhDsmpi{vo^Y*k1#qyOO^>SpJL)n%ShmC&n#J%#@uc!E6yQBNH z@vpQl0s;*S(yk}Aq4n9=C?t}`3>_V&@6vYn)FDwOBRY>nYhAuw4mGBB^9>$mP;4kA zVaw0Ze&jO~zb>kuucyf0PpUt;VS+C+ceodeZ9@~JON$y0?lw0ZmNQcpt_vp|hb%kx zR6VX@CYzukA;#QmxKlKTYJ64*gFSkcX7WW#(HW^9ceSj?>})G(@r>Gwj-oxJY1j7~ z+2CXEvd{%LFN>lC+yhCH6>b3WZU;)t6r7e(2TzCW9=xL7<*xTXNieHxsx04foXuTv z_$`{y&==6Et->=rf08_k3txRU~;}oVJ!lB~~9vC`|PkDgDjZif#giEWsMhDAf z+T{OZQbyiUKe^PhYCE6+z!tSkZi=e7~33rl{5irn`^XW@-$_2yL{}2vYuWU zx0wdN05yKNt?Kd zQ1Np{QlObLCpcO>c?VkABv+^gIP8}qWq-ML`&ytVo(mL3eUrC=wJjT2zotLSc+WZ^ z|K71?>YdK4;;b5d-C%6*uh&%H9tvf^N3M;DtQzRVx29cZL4G`txpm>kSYRoc#FgpG zxO>L^5g$CVTi4#;aFc4jO6tVSUrens-CW(GRJ^L4DnrogUHGC6Bdfn`*6?Zu-KsR) zIh(%SD8KD+?p{gBrlawpeA+b@B#nk<-P+a7&NS^>7n>E?4(hG3$9uQ&>o?|Em2$pe zN1S#W3x`o2l{d_i-bqbX3#c-JYNjUIj^Y?~sttOBV|6IT1@J3=7Xo$0+K zH=aD;(Rb!#bio7vWO()Y7-lk!g(WTNqUoq%j+gU9Q=N-V0o7a9ayK{ZkbuP-XbJLp zhdY!_Ie1;zLQ^7DA7*=_Qbvr^VMKnwp=Rn$jGbApf1|d*@{wYQ?VNrNB}rLYHLVeI zXG!u>bm^c*y0wIbvr>uK0LJMe)^hTHX4nn6gIi1LKPpRcBNKDH&?A z9}#*2MFA@Q53z5aRv+bG6UYUop;xIi^xIUNFH76hij3Yshw-$?5Oam^iOJ0Wv+I^C z`(@v$iwl0$%PMxOvw9*aZCU=(WKOju+8NnyQNUya!ZkjVWzAI^Q~S1+%u~K>(|xNP zaoV1KF5%sMm)n;nfmxh-DS5is^!5fm``bCD+=}n~sjhAFGetdtn;0v*Apgd?#Ifwz zCfT9f<%?&ROW;{RhBgJ@|b&Q*V?_t=%X&%N7;!FoHWs zFAOC0O#>eDZf?d=!Arf^`uncu?0){xmjK@jkxv8OmkfK0%nBnaFdCIln1n7Q$NnPxhG6Jh49&@4<)y494IgqWN?cI(X`6aJ7O~JXFMG zWLEi##B)8)#d}3`ZjN4=U5K6LR}$&+$g@X9vwx3muF!T_MuHPp zC1rNTsc5DaHhjHcMCMOG+)vMw%^%JIA8o^OzfgohyUR=}?7gOGG8PKmPX^Ha z-#+>>4*mHAkX(RjgwPPasxAv{R<@0MxXK}7P^MW4~)ZFWn1M6Z(8h5n}b zn)ehG?aHk>hZ*wPyNCUSS&8+d2NRU?6qUi@3mdoIUcz#v|0ClwZ_;*AvHIc)axz8sg*M}JlkM(}yY6|iU z&Ac-Rec9)jI*Hs*bKiP+{lzsVbNkv~d4g|M2KKU2N$zdQ^EBz*8 zBCw@e{4H}F<}iP%yISSu!(U{5x4u9@(U-^QgiErvI>M!3^5oB)7H&{Xh?dh^-izFd z>liJ6-($KVXbfk{o{rp~N?iQr1{nEvnew{{35;MSfmi}Q>;Nn|=-5u`B zpzu)kQ{@rIIe*u4tWsFteXfj}(|%*MS4#srs#)2w7)E+Jgl7Mt+@03Gj9R4#5EwH_lbBh*u0Ws(pEGR8vv;!G^1h=(x`4UG3arY*C!2sJ~lN@2#Ptk77wvLY?OCA4ejdE*^ncj z!OT1G=nqj9B@fVKure`JMJNj{)xR>|FUi~D9+#(99?GsfQoOnL&8_Qq!opD_RxLNB z=WqB3WX1Uy^cWS7`uH713OO_-oZ&h-cAX%Bd-+>wQZ)YkJ$`5Qs>J@)C*-!jX+z*_ ziF_3_Cv&B@&gJM>9y7W9oot;)Ma7CGYWL-#24Z8kp3-z_71VTn&gpsLE6?xfE6*%x z5C8G`b=dvfgzalo65;TR4!g?9t2&E_9uZGDIy;QmI4cX1urf+mii_QqKzkXRS*q}2 z7Lq-FJ0haR341%8yX=$Gj;C9NZmh53cN%P;!4C1qtbA=N?znS;{VXH*T*QkUp`C2}}4KRyQ? zwf~;h(my@ubj~t#q)wz3=9>-MmQejfMn|!4sNUV|PE4!wyqNxAp~9xh;X7D4MDfri zPjX#n^UhwwVlZ)77hm}BYp}GYRNAMtIx73Ie`rfUd!FtP=POToILi7htw2Kwm3f)3y{{ijp zS(%OvQYF}h36(d`5Kkl8LKTDaTF2Tm=0{zP0@zG94S#HFuZmKNN4X6BE&CKiDLKx_L0eJSFP&$q-K?BXch20T7< zgkG>yus)QQ$X~mP@|4>p%ErKmExSiBpKRpU@v%vG0QWwEE?3_|_3mn>7xhc#Ml0*4 z-1uYJq|)3dv6)rnHaPaqIP1@Gd)2c|iD7!&o?^?eMS@3Yv%{5O7w$=Y|6dceSmQ_+ zClqNYG=)Qaxs5M3vKsf7_9i+TR33C@j`6DQ#C**L_uF?g!r|SrIy{4v;_^B3i@C|Z z;Y`~N`%k!IhnLXmE|(&kMU{V7ngsxRcnr3hy*0Lz^3}!j;;ODXw}c?&B0s3@E%GS4 z#_&u>P3XO?Oq`1BZC*##fni2p)~~~$drFu9uKl5aLJMPB^srgVrE4vWPMgfMRL3#J z@wlJ!K46Z4kts;R%voy5pe1EmmV_mX8|x}7gWQW_F_~7^!v1Ew-klsNV`!oq_$Cyr4{X?9PF0PmHu6&o zVRthZdCAkh`F*hiGF8-G0{l$rtQS1WW^Er^?`G`>6u(K09o8*hN?CfRePU@WCKA8G zpJI6j?CKG?;jwWP=4;rMz3W2XAC;G@usKGFJlLZ|f%GlhQ^mgeX1h&6z|KG(7K2D zTuQ<`A~PJw(p0JU{H8+(rm5|&`NxLI+vrnwSNRru#gjzh@}Ei;H=82giU`4py{rgCfosq zIJ;mCnmJWU8=PzN#A+MV13Bfn^Ljt*8R?uBH_+G`1((!v!$M7kQcf|sw-mtu! zx8>e`%}4-|deG=a-K}x?f=7GyrD!{>(dttISW?hOqx8A#mY%7#x<&t%mff4h5(N&| zjUytEdTR{b+`BdI5fv)Atin`(HOy|KmWem#br5@hgVnO7?v+pA zwy%%ZKP{;f&$xeY+ufcl5Vswb!FN{lB^0d%8-BvtOKw@8B@=$_9*zHr5j!%Uj3QH+ zi()uXvu+oOp~{|SLsjAzdWko^)S6x_0}$zPQ=+WNzCD869SYg^L^K=vj(F-V)~pm6 zI?U~E=AMPbDIiKuIY|lZr>F2;iKte@cg%Wn^@ymIPVsv^IdH&9sd#ef&S@LiNFd6V z==15&&CY#`)OH$qnhUohEj23!j~}4U4oJ>^$|Ln^BMGd3hn+YaLCcF@m(avR*IXxB z&EwQ^^(@$0Li2U>vG0Q-d=Yrioe4y8PN=v1Q8hu~X7!UKumzPR*P8#7$D2V&FSKB(af|_eJFo?mE^9Z>EoBz}760=_9!QP~MZm^m z6nt4;0O1uZ1}%k4Dg<_eCLYwZ-M1H{hf4BmXXTryl@(s(SVtV{<&#-n zP}2?5ZCWx+f!@A`&-Kw;gl#7wm?t&IBKqSYDlP$BCU=?F@(v_UV|cYr zK*~>Oq1uRRJ1ho7D!Q`yi?J)BRP4CT5rWC}2f-UlnQbQnJKDfj#HY>vX`>FWZ;<_7 ztAGT{l4C2;itTpoS}}E*e42qa7&eB2zGiR^OTEsI%?ZX@2jhM!PcL& zcckN4C#aR8`95X*q!8Tb2u00{zN*}2r|kX z2;XlGPL-|`g?#Wt95l~C3j^OD^KYeEuGEzY5B~%D$s?a8z3QWOCwUCS5jy)iEiki$ zcSMs15mblwutO4k3QwKhPQc5R7YsweymS*)rM zC)9nX$22untaMmK{kPf;@lW5p;-1d^rPuLKFH?5rW;_0lh~vT<|E2LvBlZnFsHK$o z>?3PRk#7hPTY!wLhB|kP7VOecOql#c$v^I|HiF%@*-hm%)Mvb=4H3#yqiKIU$C0A} z@2fT((nu3dk^3BWDuQqirlYtOQ{1#BrF`Kfi-3)W@M9Jhxz_P{I9TnY+?(MY&&B## zHfPk`)kA&FMvCs8&Ctgz#?qat#>kkiZPPdTdN zvr5ICXt>8z$!qp^u}31~()E#l6M4kINp|{E3&8_5C;ZmF=ZToi_{3hNclEv9)ROcC z50NkbDVsNoAzRG(bbxoHdn*>?P9EDT8v| zt|C_A4VMfx{Z>BAb^?k4j>j-e zMHwq3SNL9mm4%iAMHl_UO7C9tnzzM*PYsZXbH^eTuL~MOI>hKFhM)9qI`@HHj6KYj z4{K-5ji|ht1Qp9FespuAT|jcc@o{v| zGApmeYox%>puBnT%TBXPI-n-IWt5c5onpI8hnqgi_CYkci9Fj_jb-k+%ITHJm#>w) ze)Tc21E}GTOa|!>tCm#`U}9Q3-L*^6RL(c~T3r_h1~#_#YpYEr!%)N+k;58}B0*k^kv9 zfcRB7l8oF{C=y!^*uw_X*h?+jpCyS?7SgP_K5`Yz3K1sjCM!m%5PlNtj?n&nP5l*<@l=BQ>4 z^^F#B7k}!B+bgGu6M9;|`SWjXUUnmOH#l=XZ}YW-kB{Ph*Dky>`GPUEfSyO37fXV4 zp#|2#z0Bj*5;UB|r*z3H9!w|kIh$C^#Y+IFft9xpk2{UyDZW<3s3D7+{(izO)84Kx z;5LdFosLOZ`tGh^@%hB7V6en&*C*A8R&6uB#OLatiEA#8bD!Cvu5XzY&JfLL4c2Sa zeny%-ZiJ2}NzA|g?h7tZ>5^Y%VPWUH*YqV6Gb5$=Ip@d)<#u=Yrqav;!}KGOE*xEg z&z7z$keGD5ukGuH4KM+8M_jSaNux!F7OERkbE(z})QRX;=yPM^!Rh_H-M&^BUfsa8 z?&vH(a@U-6glJ9BC1+#dY!mn#0i$l1@LJ8{tBpr5L|$i`404Fy&Dub))?sdfRmvu~ zDHqQn{FY6_Jy*^vFpBnDD)*6a~zgQt}eR@y+|JNcEAcp#*c&9pxo+V)P^9 z%pA3=p<=x}-k(Ze37LgeJXEQ=AoSj)`9KgRcsdh9V5lfn;V-A#9A;uyA_;{rgcQ%u z^fKul`xG$C7}IpM?$9RKF&*2VpD_r@pk6W%;edq^l3BvbF6SVhSW*WTT{aQ2*FQ+O zoItv@;JApFUrBrMhRn74=!%52V+{E5JJb#vvJ@HDEkeeij{-(=3qE>zJFiR zbMhLF#~!(=2dVz{o)4&_?fxaBWU<9zS7|J_xD%JNT9FsreK7g{iC6Jh6)lx9Z5K$p z?ezS_vthhS2C*pstkC!Iuxhk4pGh#`Nd|l?yk|(p`D#dEZ+ivc$yri57L1%PPSc;6 zH+wWn-uB?h*E^ZAjxdO-R@S^~)-Abg@9(ehA>i}g>5C~z1DRFsB<`DpGo;4Et3z=a z+HM)!oT-KQ;~Tr_%&i`VB%Qm=Zg#W+dX_~|U+WSqI@~Q2d0e-_bcscw>r&fpH*~uJ z)^5oOu$4_P)6vWM!}@bS9(eI2hrRXZ!C}#H?e%YNy2C673Vql6r9fSkM>v1jXEQdq zzERh9h<>naalhqj^BWsbo@rbFjPBrr)$j!mmq8}KQM9-57$Ir@5b@WyW4 zvL~|VD83E-e9NvQWOe~vyRcA`j3nb1R4t&foV++O(EWH$^v+~1;+UXJ;8GYGVP^BY zJlhAWnTXS;1v?(thBK{8a+Igig$dPkS$?!Hx{xEqvAyTjlt2|N*2g3VZ=>$pvFrs~ zUhHT9xYrEFOi+*w1M>Bn+h=oUNX$o^ z$FH-Z!(g0bz9R*>O$Bm*vJ0BKZ!}Rj5!N8{CMxJ;XgVr}<{GLkqNQ{#SWTowzo_LX zAxB|%oobZGNo^lBwjBob$q=M&yXQ$kVe^mnP4Hfeuzz;3SC(YM&cnL$POfST?h=RG zx5ug^%slJc6R4|tvp?U)G^1Ttj7mPhyc59R5$A!B&BS1tA|s0qF!zX2UPC92TC zpUpvpmCy|%r%SnrH^BMK$vvAebbp+K1^Ho5(9HR`+cY>GjD##bk7!QFd&ly}t8j=( z&L>EOEa9d2dnZJUqny6F>+k4x*zw8`lOKCaBM`n*0t#br!Vm{{Rgd>Yg=rB&rK=1c z)Ax#}cO_t=m*Ug9@x9|^8Xm*D=2{?9%ad*`%gxd z6T{n6yAOomUEQE~j|c1}(FMmrAK?!O)Ps8WV9_V?_dcVY+Ze{c6$-hV26=5Z4ct=; zt^$gLB&sg4WyZ)Gq~l~BCesr5gZ;+7f1|>>+zPK>Pz>b;pF<+;?8%n3%1~6V^af(nI9m3Q#lytUQ;ZHSSCI;e0k7&gM>Dk zeKC`ZsB=s$s}F04prg@%Nb`lFAYFw!>aV9q;QS3jN?*{&`jx%38-QA;t(7h{^kWyh zEL%rkHt{Q2h=S=1q0AXX=)cGMXhnoG#fwidY>RG)4rUR>0;}>GqVRv-3=4m5f2g`@tV|iH_d0Q&ZdC{*nopYhR7Sb>|izbJe?0)bM|c$ zDsO-?fETz>=%yI;-{ZTCz0byCODn}MXfpU*|1+WH`tXRt1Ed5KyA(-JRi2PQp4{u| z1Iff2zm9Bch=)F#DZP%G(&{D5;1NO7(g)6T(aAhwzofHt_-B4(Pc5vf_RH8y%*eK= zUg033;u>HD_EDwJP;NVp6N2qm1+Hbrkw_&#Q6%gN&xiF@h_fQRp|bJCY&%1@&wI=3 zzuY=C2^FFEv!IfSPbbBnN~$?WtwI>>k;D3gw?FjwK%w$C*c_e5?~EvbI5| zjo~DE1|uDH07r_)GRs(Zo=9l`dmQ>9YR>gLnupfIt@UDUK2Vh@ipbGKHExpVYyuUe zg=VPf0BT*zha~R80Nl-}^M&2`#`ld^Z!&W3a^z;GXLZ*{L!_ggmjZC2;g6DC2D=#g z0;<`(EB2~P5MP@Rkiqra!pyuaDj>qD^^fqQHYPl)8lEQm zYN}3gCJ-6MHh zhPu0-iMT(1cOXaKtE?kn8z?({eI{+onG@v!TOg0iw(u~pcQ#DLKXr`S>{Jv?$+Ssg z_w-K-2o<;k;7rN7o8Y!i&d23T|WA8g2gO+!Kq^A&6#_Ni}!=QM>bSbXgq zJhYer!97kGe;1NvNE~bgK&O(?O6=F_X!P^o6E%U8A=nGtVnKNg{cyn-<4}7M45U4a>B&ZUbpK^Oi*+iutgRXT^YVlXRm97P}1k$Qy7yw3-@C zFXNujVeqlJy;85~CtLed$rCmXxo%p#2KFfpU_&_z27cv=7CWH~o^nD=xPUGn0~A1L zvVBa@`U|%zo3od`#@f6FP!$I<@tqTD0I?#F4^t-T{}nfKCL=Rd^7Rfmag>7-0;e;M zT6NAIIamPT*g^I@9)U`K1&;P*t6!WvHX+`8vYn_adOxGEy=8yn3D5bBFVMOY38PA0Y62JDhBq#C!VKb2g5-muGC8MAj z+?(9ocj}WXzH)CG^{A5465I4q>x)(?`%{N}Y{sdC>?Xq2-8&^O@1N^Jrge5?<25-i zsXA-_tSAoW*r8#n=0z0o>~Xw_65a$(y%9p-zF-x%|8Q_uV%wTh8oT$Rm+^*0io%-x z(+ql2ovtQ$wqH&|q-$ztod8J^aS zS--2qG+Jb#bZSJk_i58EPu2Dew7&jQDQbznbLINq`~T_0bi7~Ik*-0-ZVQ$Bc53-- z*83bSz1^ayMtmG>Fbm+@ZTlX@X__gpJbY(&7|#HxCPLFyFro)?^mR4433lC@%_Thv z2oYK5ugXnJ3D~-&Ih*iHr>rQJ0zaeKC+rZZ!#MHDENJNN_G-?pQHZX{-3H6+BjnzP znz>%-Z7OF!(|^9$4g*-SR0a1~X54TzY{$#qerC&%x7cluflaVHh0+947(cmaE2k+u$zb2S zuQ=xy|pN{Z-TW}1iX zCZ4a)mPEezVMxxp0#ko&>!!4obGwFlCAX0(r%zS8>}k*<4s6mru3iI;R{r2^FP_28nZCa8V}~U zl48&MAReVEG6%7)-VkBK^czt{H>nVkr7))V{g?UkMWxVjE$9@f48^sZb=ztm_hSo+ zy)wKQ_3hJBHuo^$aAagtwXiC3M^tZvJ!%oWgUo=q^dmN8zCy7=h~{MLscKe;GM1eb(P772^E0>yno)M1t8)ucgL;g~>`#Q=*0 z!|j3rKWSUCRlIwR65mn!Q>N9XIOI!F)XG!7aT_{feen)hB&db-hsG;)iOY#iS|X_m zQs9y`X4|-^{0H>%$y*CKJf+nJ_sNqE*}xQ!ka^`H zyRz*4EsH_2$0sQjM*IkSj|)L6#k{Dr094C~0QXrKVG&J27*C}iRp5BiG6(Wqu}6D4 zu^l{pctnpadn4O97DK9*8RFw(dMjsX8kx4;f&7TVWdty;Zbikh?@mrFsG3-mvy%yR zuyq;Mor>`rY_okBLO>z%_xcAp6wo^$xs}Vgy|?g-=P2Fvaw_o}B&7AH_dM$+*%@(6 z8%fO2`@d8L=<&p6W9aw2TgpSm1$g%OFW2C_XKvv+H2d>3V} zLyDU}Kw|O4pguK#w_RBe^RneR{W|G8O$m~vN#K2H6{05oQ?!=qcn|%M%xP&{9is&bIPBDI6MaKHzxdDQ z64XLp>?($A0o2OUX|*NGYxFdVy8`<;-hWImMW^S)}8_D!_#SX*SOlkwp+xL?eL$F4%JE-zl@lWbQb zbN^}}=ju%v^C_P`CBf;BQaCr{O#?`FAa-@=@(jaUG${pcPMks|ss))kJ1l^E?*Qbu zYgc7m>eUOg+7-3fg6IIz{qQH8}Dw>I2>(3T3Y@l_pgzsx&j2)zh}36lK$pM|BY(U+Pef z;cr~Q_i-G=%h7f*)ZG`nZt=(8RYQt^td_kOajvvhC_&a7M~f4#q^aP6q2*$GPtHQ? zS|vKXNNT;UDSvx<286o%D<}PyQK6=kxjv`-_y=;E`-7h8=No&vU><{jZOsiBJ?_s( z#qgBOE4}*)+j@5PgF3A{x;)qXxCuHeWBTLP%ME9458Fb(dN_ELQtgjos@|qVUO~xx zJ?5C!hTH}f$cKG|iUdF^U_i;|+QbKE0aY*JwSv z{X44lB@)A0zg}1GXlhAYx7@R|R2kPl_Nu0fG2`Gy;8-yCV*^eGP1$s$ zcHtmhj*h^r+r3w~!U9i%xMW_;4c*9IDHmtwi=4&e>HBj0=x*$5NatlA@XNquODWBi zBh-t?3VOd!eSbk}D$$q-X5!BuRS^OI8ml&=90HfAHp0pvGiNm>MLBGS>Sy)6x0|VV zCMp@Rr9iRT2wm$+1|1T>y^77;RYQJ_@dm`Lu1Er3 z!ct8#PX$Jjk{>A_+Ok=51hO`X3L=O$6J|9l)@xLzaZ|b2BiSMG45n*9h;WTq`(xHq z$k8{VaA|9u(M7+*-3}^q&IJxCaNfP=*Z5yW^1pr?Q|Bxd^R**p&IGxO@RKyKB`9}F z{}^^-i4%WMGb5pj#+|E|K5?@%L|jX4V(^(-VX$Jka`3)m)~R9>qt7t(a&(q;#x{T` z_0ZdVsMV#;AnAueDs(GJrr96Jm^s2a6)I+g{9s6&!xb4caP$v|G~ZkgZt7COiR>Nr zy4P#p;GJgX#Rd##6G*`#=q|_Y_m-jH?LU4z29uC@ACOA?MXPC7?L)F%OIc;_(URoE zIwT$+52?i$p*+rrcH_h+dAQ&}OGKVZ*L?y0i36ZXNBnR+o5yvae?#G7m)EP6fK2bOQz5hbHRWI(Po-*%^Amx^X$Bq?LgX&~Yd=&exELTbYn-`{a3JwvD~3lQuJ_wQnufewbY!BwH6(u-@e##x3gC%!f;PPtTdiwyr>J4F zZ<>=ek7)H zzf8_?0TxkTu6Y!fGMkI38x*WY(QV(3vYne+5F@szrEJ9_fNlZIO}9t0;OZ4@V5l0C zJyN5Yr@Yj6IY@7v;UkiD*3Wpvg)v@J#q6Fzm-l-FExj9}a9%XO;lMeoLx`{mTEGAAGqc<4I6k&QIoMMtdp~-d6mr^(Tda zlSPo(y3pWKCSSVR(wpjjNKl+eF8ty&VJ{v@xMo*q8L>zZA{DAPD~0AUyInpY-=&Hv zY&nB`#CN~UANS}-P(vKEquw2R4bSF!B{=3C>udWqAo*J0+aH)5{AVl|=qi%jMs<() z(UE&UrgV~cn9^TuLziD^wfO_qkZ?RUKkrPFl&cWk?o~iJ++AV8=v1KZ#R{!HZ%&kJ zHXgaykT=b9Jj#vv^HKS|N5OTbtli_|ArCFka-GXcZS`sXKN+i+79TqmMX}AA_zES1 z!yn4B&S)rFn=J0LPU`@HH#8 zX()E%_%DYv!`7qHUyFzUx&0~&?Rlfe>e`*d7QOKncScxB-5cE~u!`>95GRHsp({B2 zMphdnNc3>MZtJ;M$q#tX?;oA^A%~p-e|=#A>#Uyu<9$T_vFEBtsF9evbvD)Rvb~l8 zPHU;)zLVNNbqVBzd#DyH{}4Sn@+RxgGY&b_Z#$Ig+62)$vtowd1c`rEpv~nGO z#qQ#+H4)<>KYt7aLIRlqT*Eju76vi}6M ztg(jg%W1D5qM#SQ67hY>Yb$x_s#cnza zAqU2R2!PRiHe!&z5jAmBH8>=5ii6j4@X9zRe2)DS7l%gtmJTH1n|v=)dCK)=h_y09 z=&)o@b;Er__9!yJ&OcqrtrLZ_+LPZowmbE+j!FoXB_7NB8_CMCWh2KFj~mZwWUE3J zL(l%65lgD8T}jn#r7c)xs~-tia^WJuTr-200N;ZdloxeD(oXQ1 z9p}kTvfXh=8R6jcKwh@FWPTFk4HKV&DiaoTxGpqRnJG>@9 zmY@IOs_6hib|r9GYQw>INMW-!a>%`i6Jg>jZ6DM|HJ z)oqXkII9AE{8Dh6itK5LkVM3I6DM*V=oy{n2$}Y%-*9Zd04Nzx`tRe*}c>{lJ)xo2M`D>Vb?)B&|GwIuiSdcM0ock+5LQfdA`0_t1XjLYt!h`)a$X(SNR^yRkzRdOFreI%`SvjO%dsNb=qa%Z?>s zp)m=qz#icMTTRM%`oMrm&$6k;S8X~4!Dg>1L#jwg;%wtr3^C-!;fDW;;J~_3*r+z~ z#}0TE4luBXIwmh1BG^rfK&CGp8mcyd3mG<|`kHfyf{ob8|L+orSTOi0#!N#*%32_Q^kxmzfk(I(EBo6xSFqiY=76=AR}=Q@a*&PiPVGQMcKG! z^?1G4WftK<6Cp^mQSvPvBYSgx&u_0aZi*>$I zP?D+}w4X2HU43&Z-?`{Y!|E>bU44GY$MrdeHl_f9VpQdpT&CZV?wtKk@vQDi{2e9k zma?q*5NNF^Az53x7=emg@!a0egVITLfBr>xq!!u|iEWyfo-&f|7WLqMR-Gd;QnTE6 z>Uup3^Xgp0y>IkO`UkTk4I=Sfwe(wiewaYgVes-&IaUwnubgIkO0QxkZu8(Gq9A8J z@XJD&?*i5Cm@b@pcn1Gva#9&k4P8;rM$Z!3$mr|e@K<6_Y)Lo)VlTJdwINaJZToEQ} zQ8zjC|MT2Lo6l1VuX`&SE~R;S+;&_omrZZTiSX?OZ7E>rmH1W>;R_9rXQfZJ)wwhl zln!u z&VLMm!T}p)a=Hy{tENVDJUwJ5VWEPeygqy%J?FL~yAv^Ar2AvFU`e4lU6A zo#riFf&dbKmV@P2f4;+S9FJflP&RJu?Y4#3lBj1qwBqLDhP2j~6L>HZ@rSkhQqfC4 z(aQ8M<*uKHa*BCI%iYNBt2F~aO9(Si6?cn84t^=L{QOx~q5q}k4Mc|7#!SIK9jEri zZ=%e#3%@ryMk`G`Dj8rJ?BdYP8s9m;{6=ALLjI^m^xdnizv*_KA*;KFJ0|hhP}6!H zxZi2Y(H%b=Zz3G~{836;5;39I=R(={X`Ba{XqOV+x4g?!Gf^G5;By|2C@P^C%Ecx_ z*&pM7z)VLG3*RNFl3(-BxRq2N2L`@#E2zzjH(*6Bn`T_Y@XFt-xeHshe>`{Hx0N4k@fbEPXP!^Dmj8-WVVe%PXy--HrO25fR0vfnCx@xl(_zAmR zIDfRJW99hUy7`SV(9W=iSji&s|En;CdTWUPKCF5EGf`3{@7+GN%QN*oB|JGFhhxf4eMU*E zDvd*gAgTQ3BXH9&eVSishC9yE00kHmPW$3mAa>};=M#S{=skFK=)`a7_~Oe&Kdo=U zVP%M@)qkUu&8^UB-)Yw!s9s-Ij=0~pem#*e)>XZhwnRV7+#+O9x=2i$=t6uMNna^!$bK!MlgJzG! zq~4+M?HPe_qO2POg#y*p z>b(P@{^Q5-LlKEeR(6q*5GC`hH0;RAPLgr<-cnSA?0r;7itK&Jo~LYwv(G;JaJcXD z^!|K5-{0@~hd;cYujljmdhGeU&KC`221@mm|dJ(o|D4|dzsVWgjX))uF&P6tvUHJ9i$NnM?c%wPu?Q zusZ7nJp)z?8pU%NO!=!C&k?S&Gsrr;bm_J{`>dsWGyjH`zpOIWq-zjw^}xSf+f8BU zcOI-sDQ95Zg+eMoZ?J(X!~4uj>g^&9WLG5(wL9kEBJp@R^kU5|Em17Wn;b&F&EWTs z`DI>&7+Es6P(D-8>u1ilx5OXmbx4}z4Oy=oFk0y}1CGpt@zKd#5<__~1Kc?Frk z{Uh+69J3~TR1Mo)#8n6Q13Xrd^o|%D>aiJ(>i!%1dy2_!Lg5{3ky@I$@##7>TZp+T zME0M7vX-~73N9>0CAYHe!sxR^Ix>6FvMwH};d+K8`oS#Qz zO?hab?*ej6gz&z4pYlU49A0T)G2t<7k+otjpX^Ub3rFu%ef4|3VUfn_NPd($k|7s* zC|6Yc2Jzxs{*>6j-FL(N?h8HylbYV4!Zhn~vm@@+A)Xcp$nof8-98#mw+8w0fYp@` zC`?Z*wC*cw@Y8HLE1wZZ^{iupWBayCE1L9fyR&-BW?w!1E@#xXHsgm=iD7OWWk@B| z)HTZWTttu2ul$RfY|9T-VXFsKYXqSawJ()Z>bYEwtzp-dGt_&jwJX*?uA0-mu=;** z2pztkKjk{yZ?~&lz(0J22uXqzO8}M|%er zH_gXNZ==PV4p`MTd^PXT|CSNHhPaK)gPN$BKP9ylX>?51*j1HJ?xzC{G+?~+U>cs1Tz>o*$+NKZ5u8zRh0M|r2 zwtkL!qw~`N7EVVv(ThDrCalnFZprCkfGPAYo4&K^Xvs3yVq% z#|OsCE-N1S#Qt^SNKhia*&kX94;`O$y!SyiJY*yKSaaf^c7*%_mG_Wt-~e^Gr+EjO z5i25yqoJ6HK#dgq8sF>*xCiHEOGZykx4UoF|6O*TLK)H!;n!IUN@%y1ek(Ot3V|AI zU^IaBH;PUDLhEYKhzZAg%zLOEyli`|S?34$fDr=L0Ao6SDs0cbr$Yq3950~v*2A1H zK#BKzm!&*$PE~XNNjn0Q2CS4RXWZ*gF?^-rYD>dcl=Wd}PcwckV-y1;U<50Enm~21 zxgP)qreM%yss>|L>q)dVpvts4nAo}|v7`zTYWurMm4O0zWYYZ#tzL>w;##fZ{1$S8 zG}0}RC~`plHcOt)_^`Hm{}MQN?J0yexn>bFxev=f_HRKP(pM5D+i~ZZPGvo3)0*1n0Q}P!z9SHX_b_tT@F0zC;0a4UC5=OuPhb}%dH0UeMP7Y6yIh|5u(F4wD>+pKBh0HmnN z#np2F7p0h56F)6CFr(oL@nES!GPNcds?O>^ZsM5J#apay|HsYL@*t3MiNwOYl-2>B5SnAvuVfBWRc#V%gx4u=&` zZ%@B#P6JR65YmSERUqa;OfUBMkLX`{^hNOsDUD8*Jc~LH(R&Q&vFsh~8_;oJGVZ7k z&@c}Fef$q*gFQRm;O-aP{%rQ`N7VAt&c+b=Q?$+X((sxKz(b;O9|_@8r$^LLJutRa zSy*2Pkbas5X*f3EGXT!|=`yx5a-Rn?z$7KpgM7Fyz zB#3x^Cm>LOAd45nqd{6io!CO7whX6~qbq5GDUO}DsWSUYBpn9O)(**Tp~R*+zHXyD z`1u@}bHT=tto7Omu&T`uG5bQ(7<@Q=8Z&5KI=u=v{LS)|1oALLHz5jV({=+O`?OsAt0MYFl z0nOhKl@E>Dp!lI>)q*rbIqX&(;S*@hSUwtM|modqlj(xM;cs>dlQd zBd36!#u&opctsi<Tw@u};n$8U3szGOo zEJ+E(jbu+ar@27x7eu7%CO_b=pr!0H-zRFfj@Uw`5j;nc|9v0`w?kC+`C~430R5e%E>8ye?#;RP< z@?AN=e-6|LRQ>OY6ryx$UzLzK(=tEfn&Lg*dxATyfm9RNZ7ENx!{6AHT<5lcn{2#h znU$bMB9&VhR|~Faim#my44_~39xd{p#|r8FMRW9KW-!&u8LP5TK=g=_)T;TT)%Qr7 zg?MSa+4A%AVEYS$<{XsB>wYIxNOj??uR5U$8iT0qP2x{CMp z*v_S1z}FYlYwQ*PI0!fs(~HT^;kCo0;y`xxfVHDkJ;uTPvLacssq4N|N(_UL)Z0DGmWBLnF2Ol(&2uq zR4>2GkY=QJO=Xl&lO&tfcjWCcrO2&CMTGY#3L&e0puO{W!Dp=dh$sd5e)JqQcztg# zk?J(APcL^Ys#Z+pJZGg3y1bMEE7R~a1^ni08g%#%CdIe11t-zH_TA6E7Yb*k{({x! zbnF~yiArQWl^-`6#_x&|7DVO(NyLYgY(+GTruH+)FT@YM6%7XNXe1Y{(s8g;Rcn9t z7%mQW^tJDR6}dy)|C{`JN9Ti2!sP*u)_UTwUj}syVE^m|=zV!(ww z>sjs9ltyXyqw$_s#1kNI-PLkg;j}4wl zQ{BcW7M%OSVr-Wgmb&kXeX4x-x$nD1T9e@8)~Tpiku~c>?dFCkrdI<6wYS`|R)?8W z5bUP5;hQ5+T`i5MH6Cj%W0strKJoiMLP|arqC%KWh1br&zUR-4(>$ydW@V6xdKn62 zc`ZnhLL}!hf)0PQGn&+&R(^_9fxs&c)`kwGV>f-}tI8sHZg}eUqQxuoh6-66ONf~* z)rpsn+QXZ$^F=}$H}k^!t;bqz-mdZJ2R$3E=t+6q8Yv)?Grs;{HO!U5AjgOL89C%z zD3ColLvLzhweE4j6w{qqUlf4&&oMBt&27WDV2!fSFKZ=zgu9y<=(m{9Gp>Quzh9A` z)PUHvZPYQ8JcCW|nNTi02kPl_mJy!C`R|UjniVydR_Ri?!glZN5X>Nyop1{0GJ(&qKVLz-3`U@7+($57V|} z98ULCGYQ>=z|hvEut#|6m)#;ePs*+oQPx<6MuqR!uUBFHNqZfBD_v}=$6I;}C1ovD zz?&RKYo6D9RM3!n>(Y3+D*c9WVbQAP%Lci_;(G5{3*3JY`KBL z9y^=z4B#x#dM8y%sI=lb*3jeE(?W-b)xO!RGu{Np5m`IyVY8@IS>*04``Xtx208d% z{kE;iyG-lrkB?33{&Ix!y5lX)T5ASe({7&Vj~t)p;803#=#3JSB?j84-qS8s;838) z#!fk7!oBsdF3pCyEV(mxkTo3j;`<7Z6jI9plk$rG|5Ep@dBcDo)*G?SC*O83{5q{a zvJVgQ7TkJ0YCXT6QCHveb4L+sUbgvrNJCT8=wI2vvcyk@YI~T5ZSHOQ^}E+c`J-O- zSL|lt<&vkKO=Q>Z9b9qlH?ynh#z%hQDIEP0*jeX(eE>Tjxm$zX^{TXFL04o%DIz2> zTyU|1-BT%$*(KBX>&aYr0ooyFetQL`i8*Dp?XX5qj{o)9k}`_pY@5|H_1u z|5ql+tlYi6zFph^&E-qf_CFr6d~Z?=orv^8GF_f>g<8}w`LIf&o*8Y75fGEKytV5z zO%i7Cq(h0Y^28!&-3YZ{$SmcGO}orST3cdXu!ZHBHy8ZNS*}ZC?5cx@XFKk<0Yd<2 z^3T=L_k2h4t|6C2+D{U{Utq`|eol8LYgI*l+-H$C(G}fz_pG1}UFQos)pRAk1N+L* zph^>ri%?Ugf=wQhf|q&O|4}k1E3LmZ(CSK&{P8xT$35*&bY|rZ%h5T$5H9#$+RFAp z^pCe;$%P%WYE~k59+mMA=*N47f=nSWlP&{j#0RMQebf*e#-^1J${L^VKC^$#8JB`( zCY=ERqkrDnFSR`QOX;iL^_$7UR>8;BTet1<5QsU~lPk>cwL7cxooMFn%pO#{9rMbQ z8o_wu`DUGID5+2{uHwyJrs>-$`uut-R)U|6P7G-~ry)(Xi+CjSRZ!#nt}ai81+d~k zHdP*kPmPMnc8%tD`)pHMVBiQQl<$makEdPMr7LrStW+ppRHnZ|=P5jV__p(99*MIO zsh5itw@>~px3kLx(b=-wVL_Fbk@~~ZrGH9D+mfZ&Ij%S0I4wA;%tX~M%#C#~P8wXp zPk6V$WZqbeilvhJ>%O;U0)DYpa{WzG$c+uI?GuE+)(>Ka@U)IO$(ZpkDR22(_!>Iz z`=4e(xkQWo+~aki?$;~OH>3)H+%mNdM3GwU-X?bTx|YV2Z+qXs9~n$Z2p_K9QXi4i zT3nBJc^`;dxjFpzDS{`1AZI-=sd*XS(I(3A#nFKdheK#3+vBS>Hn{*}H;~@pa@-SP z4&18Is}Ctv*h?rIIb)dY!K3uQr0~O2ZRqJn?da2IP{70{Zd}Lxq3FPX+Yb-g{L|hN zy4~FGgxI}^wUL80LNn(|2BXD|w!+Es4F6Vt+8g#C4%FD>pXJYZOrv;QO**^KuZ6Y_ zH(SotiQF!iH`ASAeh?}F`4$1P^AT&HgSdk|L7#C;NT&S+P>M+1e%kPjqw&FG51mG_ zfZWc#V#=Dc-S$mNFDp~2+n8{d#BLq`M4w#xTXIRA$0~9LLthGyalNZF)_{E*CB`F$ zin_k$h%&n#HQa@dmJ=J-VSInwY%vd$on+AjP1zOE3CzOEDjQgJzSvu?iIxUBduou( zYrq#_(pe8f?e`t47g_IexgI+ZqZjgbkv=;0aS4aiizRtA@3+NouZ#%^i?wQMCeRe~ z-?E}v){<0Pj!I_D-7AjRmOF0~+@x<&i`-`CS>JZ$v5NCyB>*QQnHcF(YvXeKjt4Gu zKIqy02I_J^Iy*{e+WI-?zyQgOJp8NI_F_scqSENB@#pEyKb-3Me-rc>^c|178-I6A z34k_$T9u=!aH`H_v-iXE+SzA>hy3cAyPd+`AO9}AzJBj+*Na=i@6p`ssw)hnkU65K zaC^R+J;Cx?1|bfA!7p|V;J#nA=RxctWrKer);Z{;d0XWUy4!hM#esK?YFI20W<#xfqbPjB74O%c&#yv3Sdc}>eR@6*gdPI}<#izq9odUs0=PbgFY0Qk+a`3XMKrSJw&bKZSrN>Af zQKEn1m`){{$Ek8Q=jMnD`18v+xQ)KOKz^3$>(flA)Cbj{T+aCf_g1RR{_8IMAWU z0h7z?0ZLl5{e@`vLg*pH4!nnV9sm9Ny`gA1so6ZTs}E`}(p%Q7 zJ6-#x-PP&^b@$DpaH~hOD!%5}fTZ<@wP zwH;^W*2*$DC#T>&{zBw~fk6CKDAD-LN(LyQ==SG*XVvgj9A@wYq zN{yrOVEkQ3G|}naD>{dxLsl7|HS(NG*jC3&Fc-(n0l*u!Za<`iqu$_y^0Jz5&p7|a zEcc;5$XYrjB*CNJ*XzG^?yV3^v5Qgw79{q(zliuC?e4sM%n^K+Va=L4bVV%bX7&YC zgiIZ6$bmnElNjS%{nG0P%@3O|Yfo!af;9nvnadD%DmMx*`N1oFj?>6yBKMAtnY3_5 zOb;_#6m$Y+&-;;1O?m6;=tsVWRDuipxZSOKyrK-PU!hy=>FmR)AXnzhVnBF~d{MGO z^&{DG{0roFum_45rJ39Gc#gKdWS>tsDS&=FietfJktmR*X!q5X>u*oyM(gxitxl%@ z+#ejAffNJAYYf3`2@?tHRLY(*f=hpoeIg_c26XRkt1Qu`Xbc z0Ie8DO&4$zBcXGxzDg4Ik@?9O*P|0`z@sov^)bQA0dfI13Nm+I2HDA-1Mqi8`C)q| zHmzxgaRMV-Q7!`(_2!lNIlX=>ONUT~1XGw^gCE_h!QZelZV1GMD07Uec#-ugTR#}M zunc0G7u;i20f8RpD^3nJgn>&ECwnB|$W$z0*1)&sx$$zRowI}aD63=(B&A&Vd242d zL|`e+F@=&)NRUM5Mbvg|LcJ@h^iuu3-Fa~(f1xGzq^mOfT<3m}LzrX%m6jHr^A5=# zYBaK}ny2wP;yx7^Ua9+4Yg9(r?-h*sgSDL}XOxmKUHZ-ub$$y3v%5B~Df_tRB3)8* zsi}F2HG>61J)WldligaV_$!ts2QvNT&NcLIwl!N-Q&?^K@rBWas}MfWBLW#~Kh{Gt z0s>1b{U(;-$Yvh~Vk}x?UXCnxo}{!)IH&KMSZa;iJ~&_@GoJbGgrS6gT-y4s?EOxG zyWZ+*eMPdT5C1-G&JU`koAl7~w_D?BZ%fU8uBoIbmCsw!2uMG@OA-`wq=zZ`l>r zwR*_v!VR!^ z)mQR&KNUw&OCVNM)g)3FZ|gznVMDinseh{!gN?pAwawpcw=1{*WLdSV!eSp%nAK7a zZa5Vyh^S`o@Dz9wzhCuHfEqGKWW=YE=z>VPyEg%#=+`UY9m);Y0snZ<))l@DOw@fu zyY3~t0xzRnD<}Vne(CHB6p;1@ zfG7Evqdg_}gkxlC#z~^eo51w~?bqGsf2uRJElcD#BiT9*8C#AVwttU3UbJ@qto-Qw z*p3U^n+<_!F;j7b*`Uj(Bt1u}ss%YZsLnE#Gyibe6MvGRG@u`%XDk=C{S)R4Zz)bv zoXr=(u3ZHHagls=dy=KA%f{@PAMV*DuRo$+>r2Z`oby%^Z!o@x-<+PWhSM{XCtUU_ z6_}D@B+I~8w$v4Vjo&G_yiLe#a5?z?1xo?xV+JHz%dNpKD4O9&e@1maL3-*BRS;PJ zpmisYwpai9fktXHB4)x!nX{uNn*Cz&IowTQcYdA*UUKa?5wlV)VAp!jgLzwmdZsRoF| zRtcOlS1Fnh6)B@`_I_g(hLL+z+j{xwhx24c5nmD1PxPM~xulHb*#ACWcFHbm;a6}j zq^emTsIs~V{0T!~*-c4qeykRlJpf;zA6DD7YIJJap_5KTHcQMN?oG@bDcCl&`6_cg zrhfX0j`gy>`FBxMGs>H$Z2UJOnyZ8Cn6ABAu?)wXrgBb=!!}38J`=e8ZrmNAg=C5m zKR{#sv1OxnfA6e1pQR$O8XLSE$1ThD&5va^OUgb++q--EIcy%3h!oQApL}^Ia+!h* zE?0hDcfqxlvuL&%**b;R4k-!HR6~Dx-TADuEG<6)BJV(4*umVyTE;Bxje+Xkk4VMI z_jdo3&8Nd4sjDkQ(|B|<5Qlqjh#JN zDAzbL=Ff+-zb%Dyqjgmwoc91;<3zueOO2OqSN5Rr0HdqCyCm+VSC>3%sg{C`9O>Wd znTGBBJYzZ4vy_2Rl^pH^&|q}Ba1nMHTEet(_*}L_w$LxZK+e)=J7?plPQ6xGpNk;i z7d5}z){K2&$^>aACfGDDyj+REpx$h1G(-(vn@hj*o+PRw24syn!w1aY47Rt~<_Qn$ za%l#&Pv7sL|Kt`QM%I$kyOvp0SG{AAPE}T zKSbPm;mWew>>B@j5^l^b1b#Hq<`<>SHaV8!(X2n|vB&PMX|b^2s>AC=P@?Y2*YPeRH>Sl3Zy01uzTGhoRUVP$e3_mUCRuSV z0-Y^%$1GrQphwR(+Lk)5lU{-u>3V6a_g)V9RQUvH^_BeSlh>Put+misTRxxm4>Vlmlf`O=p61ka2-*>R<@sUFN?sYz;FxI zT9Q#P%lQ?lidkKW^DzMjeB(!}<*IJJrRlyPQ@~RdRLN{euE1Aw`Qkl}v8JVQPp#Y_ zXIy@cIJ+YqYtiBXJ8D<_ZT5H~s+V`wh45;d6kUKS$?-#)g!oohdkS4fx{AukH-clpoP{uehWIFfH80jf;QO^s!}$GAjRgFAJSn*u`MQX}w{XHw>h` zh_58+Wp?(k7{9;Xe%GrAn)EV1GQzDczR`9;adQ?>|IdN81Ya6g&??sFCzioHYp6fm zTtfK$bB{dXaJQ zVp25PVnN1KWs9J5mNp;rocUkq$?p|yt}9w0owPId>JK;BKiI&8X?%rY9;W)hkCm4- zY(hWh<{D!BWle3Dnq>&n(IqmsWrihIGUdn=bdAkHy34pUik!otYs@98_y(s#Qjx=Y z0KqCY6!v%Vmra|HbiqwV+44pnHhjU;3M3QOzO8(ddzIZU$ES}G^h%g)?QlikOe5Ke5`86(O@w((f)p)<`F#D>^>*k=yI z4qdjU;KI25ny@UC^WhUFYY}7pn>mAQy&q)~h8fw)>Le@j)~=}wDdCI~6aJlS;HBLs zp-8*O&;uE0{2amTe~|nCJ)LT*d@#S9xw=WuOZe>-g#WNIEzE!E_+wK-pd5}02YXGY z4Q>RRkjD8J6)k7kM_H|!s1SG_rerV}m@PN&<@ZSV|HyBWHO_;X?Vdx-Dg?XRzdQJ> zU3ebya-Qg!L=)CFG-Ld>y#GfGTy=5_@Eq5WU_*GMnMNJ_!rUFAdxUZCa(h)H`gd?* zvmmqhY9VG9GQ4erbVUr`>HQs+0~1#MQIpSpvOW@0Ra1GQYXO^$8r}ou^vX<{?qWc0 z?CE~Q(i~@z4A}kEY#o z)ev(%VC7sy|Lu`f*i(+N*0*Mt>9Pc5TPyw^E(uqVO7n~}MIMZ^)>JM_IEGPw*pK!) zLCOAIP9*7q8E37v1%;}IZtZFvtz$`R1ruVq^cKg41`YJ}ZmlS$R&U|kw=s5YOUFh` z0gMUmu554$L?p~-)m5%G{SUD!w!3wAVpBh7_J)_V`#DDD?fqvi1f_WXwVRJ+E3I;B zhcwnajQKt*_pxhW5Ft`$BOLwAY8X8x%h~R_viX#5Z zVz$zq#V_Xa54Y-BbiH706yA6=-*<6k=hBfgT?XwN-){j6j;t^FQ2bVF_HFfqr(>p} z#ilN7qO`3sITW`#RZ+9W9U*Zm^{e}cr}yUZ&(E~kv?6vsx759Yi@Q);hKS?l(_jyX zvMzR4E(T&g5Ur{ykXz$0&edTm;n*fX8{K*%AIqyf8Dsl`|*A;GIBcl#CS|+20 z)MYIUBuVoYCfOINu}PXhE{n3=@&CJ~G#~*DN0p`{MQ+W=Zu;-D|0=Ti`+Q8FrpFogBON~1b?3!9AFbvV75qneE;<_N4`m%QMAM=Q zCDDnB3wsvuBO2PRL)5!%yHo}_ITtunaStC*gXY?5=49RatWNWOu@W>XXz;n^D6hHV zYU#q@6c>ldJC&-pE$54(lFQ*k^yU zJz#LOr{G@|^CA|BeYFkht3+%;j3#K*C-uP3jN99zZHoygwj@dg>F5Out;J_9?T(Nj z{=-CWNK&?Pd(Fp%F>~LGSTRh|duuR{ILJYY-#lZ|8j1$71rxUQ#HPfye@`IYAXOK1 z@LoaNy>%P59tq+Z>vb~3(gZNf9RSyLBc0o8TtoKc3S8lXBSI|;W^^SJOeD(g=~a012d9QKddHxmFSw>a@IdRI+zfo4J?KP?pp=r904&B;Fnswew;$V~f9 z>%Q5X4(q8UDG(_l4r&nkX>hCS@k3~W1q9|U_>@Yq##wMtdR%+OayrAD9N<(jpe||FAXXOguCO_@{r zPvmsHd5O6TafjR;6rWt_8`OXC2*tg;U4)Ibds}Iw{Er094~gH|g^$2|2tJDez^IfO zzXrTNSw(5IXxjC15(+w%5;L)MjLIglatrVil!(43VMnM}&tSZA3Q=0+#%s^-X5H!9 zG!g$m3@`u!lOa-Vq1?zki=(ZcYRdmuKbxFJLlbg(be(gBiU%mJX;u zJU8EOSWY#azMhd9XWisWDI~}LdlaU6rYlc~ap7}uR~6Z|>~B_Dxl4?g6b!aUKFH7r z>$#mR^Z#toiuEUA!Qt?rmJ$~n)!^Xr^TA%g+)~`i;p}&RaE8XCKT=IZ=7`ItY59f4u~0DwBeDE+{%{15AcUfs+Y z6_uNhCsnIOIRJ?tO8mX^VL086Wzq2i2(N+B;0K_{RLJxw+LxsV2poq?TLloFMd#Xp z_%q6qNVg1u2*>!!kpebr8T2z}K>_T)Z}1@svD)QmNB8u_d~S~W>w|E;7{5{)ZiOc< z1u7m=#ibqIb*biEGckhP|K8{$y129PU>71gF-^I}ZTjUqamXmjxxe$41X2YAyhLN% z3`1*gj{T%pK0REJH&F^`0GFz>Q{dbpv*NgRpFmLmMi_Tex_Wz!=%}-+BcCDlMo-=H zJodwkpdtNf)jxp33!(MMdQtZCkD>2YBE0?ht9;A4Uzwx#O?vl5q-zQ+}VKC|5hnM3mUpEIlB3=7)&q4l`XDewpbi{M+A2OJ-RO6G2j! z+apO!p@!4^VET#XKQurfMw?tN<71+jPDSciq@?~6srb3kxpw3;QN|?+>I&_#DAe^f zslY4M7u25JL2njEW0y{J3s$HP0&gV$yqFtk@fO5@0gxsGV$MLmTnf41Qt;!sd;0X2 zByT=Mqf7Df6&w0>{e4y+_a9y-Qhu~)wN$wL;p0C?<97(hvEFUn}g+-V>STMiqX?ksD6N}doi zM&&GK`R^b>9K;A`1mHOGZ!Nk_4m^0ygIbVDDvXiIR}Xb%RatoM-}{t&VLhFjPp<%v zdZvA)eUZP3YN%;5J^>tZ&oyV;__6Kjdr3sP zpZA3y`00sUZAF2=8kKoK6{$L7O!X@cZUx~PJv2*)R;e*b&FjNcPBC8q92|EGDpLSr zd~9c~P+K^A4lpAts7T2}o#KmRo_I)J^cp{|v*Txe@F%z93B&0&LCK&VR!cm;sYeO$ zz8Uucr^{KcG4V3LE>5T1E+4D>fvsEXks*|2C8yKni3OT*c9*uuRa$hzhhqFMN|JF5 zbD>qNj!GiuojCIzPOD$6?SIQeUGa&!rHlR>KJ4p1LxlL=P294R-UXHi0Olh8@pB<# zFC^M-cF0hHR6*H`5mn>C9b?f5#eyIS67=bA5XjpPB--~p+su-QK3S6Lfy_gSATkeO*a_pz3gg?0NYD?0rVC%Fyg4R~*c`kh z^@N|DLFGht2#h=8AJ_PB_q4W9opxM8{ z80(Eqzqmcsp;t0{8TEx#q1x{8zh(?#U2UgM7@j`E#qcfOoPX=t9q;t6DnB8`g2C`J z%^x+5H&;Vmcom)04kdilxLdUMuaSW-4XEZVz6@BMY z`o&p2aI>UAU8h@y9QWOSu#oruUNc)5(U!-}(XHOB6ga$Q=4A^ooDpnZ5t1 zZ-IwZueBQu|4J>nRUOm)@4eM!!MO{f8yj9s?hAg73BmWY>99IGZi8$N!VF^iVGI zefl%aJ@26)C<4S7?FkPhoU$gidioU+NxjFf5zX#?W9lTvR3xq@huB&BzV z8beI20b_D!L)O=fox0gd=C}xNWr%d919e%ZBe1ta2@6f}J*>-5eD^@XZM5ar(~5=>TpA zA%VyrFig)Uj?i+`K}3QQ88*N1Tmp%|y6ULlU6JMP1N*`3VqFDu?g{BvV=0xQ`Zh-2 zGwu#Au+L>!^K>tbTk?VY6of(D=y;>=At_&%vtoTs0{8)D$ZSU(M*7Q6?9o}KfhX-X zKj)X%E8|x~_JL`dS~F`L!?-5U?=A3H_GX2;biGeBVbhC#o#P$b3!&MSnpvam{yJ;Z zlh~qev&RmQSHK6DgjOb=oMaLn9Wco4Y|@%7#@6?nk@6{argbZdl0e8JZr3cfT>(|> z4Znyk3NO%R0(0qo(a3oex$~TtogDcjRdiaeyQ>WAh+vBN5{80+Sj-f3T#uAX-8MN( z;^fL9k9n5;6h#hMnmM!Aa@{i83mw_G>d5`%&$5$T*uYC_W;qu096_DH3R%o@yiB&k zD0bNE+`DbJQB2bCifD~!&~Ft?Ug5av$c^W8A%{+qlaN{#(Rh>2nDW!z5$^$4Y!E68 zl{NZUH1otVR#NB4gI@3=BjlcIjTcMu6*{_K_6WQl_-78QqD=~6doOJGRP1PSQ@U*} z3cX}R!Y1*m)yKKEoD!E`!4gX*!kjxjFI!b3L)6>KfU!Q!eQ}Pk@XDip30LjJOx)PsEe?fRDDg@*1HVxmGFID%Sb>y?C56$1iQ_2#}7!|ceGcQ zfy;Djy|P(8GG7hzo%^0h(MbHnaR+*NVTV+!e=(2Py5hynoVf6i zNAY5h1SapO2hhy&Z9{$}%zbgUjHZbgS7u=DmHUSv@RBBD2dkn8#|oHjXD2+@4pH|8O;I&UioT>+H3W_h(;WGFxP`gxnD3r6kUB{DBa|x>Jje zqxssLfAq!e1HIy?AuJcNDZ)T#wv$XhhLy>g&?-v{Ns5vBisWd9_SFDMP)y=BBXcy4P4YI?0v*yMp~+;DKTrINgF|P;l$wtuGC3Y}9=j zNgxK1Gmxm_&2MWpPOCOx<8^d)t7(BSzv0^k4+$%fI$?#(GOw7tNo3T#M4cE6fGBeh zL1d-I7fV{&71B!|V9vSMt?NG0g~xMK?76XS6}+paDyJlam)2gs^hk=D9uC& zOrMtOrE5*DXl%0eh;^YQuy(sc)IOS5z6N4&5$zmIcI)tyYc^}_?fzKTn++8)EF(?V z=FHf7J@Oz8aYrc|$#L=*f^L7m+?MVizMWs#)GwT8dY6D6`o4N?vJEY(6YyMQoTB55 z2)}bYs)-SLok{2m;C%T)7f0S3k8CBX^e2j?#&^=f{EQR_rlDRQ*GGfd{HVS4!%CDT zAR>3eDB(rQ93r|DXHB|pj8oLXFdh}d9_;p39VdF~hTqx8@s`O(6x+oR9XiJLJhS}> z^U7|Z3U^ij1DZt-IJp$YeQCNQdpmPi=Bs0RNnw;ah9&c(z}y6tDS;f4WD8&BvFkV! z-J^RE@=&ha6@iH%H7|bNx7~3beu?@X#3+Y!XT@?Mc+eWiW~Lnjka=Ad0rbQ@KYm%n zvq4DY0xt+zQQn|}1lbstE>ZxaQL8+WK^?q%5s1m-Jf%Z!YsMLt2Nl4+Z3C9RZj7d0 zuaBRI{OH+M81vt9-11*ukR4R(zBVle4gxFzD&#FF7n6fL;PS(5@$CZ{k&K6?ZQ1x? zkS22Rh(J^1Hfa1r*VP_TbKYUX{jjD76uX>w3Kn8~5*I(M0afvC8E*~-%(9OGBc zhJhOJ&^&U#x<%2~y4SZ{acY;v*|M#NpxJw^&WGLv&00YLpiWIAdO&9DP!D6nAkKvq z2y$-8efxqU;}V&5em4eaB4o^|(-`#o=X#{sdgQQY8-X0@8V&+KnZ7_$+ZqV1n4j;- zVhyb&AtmL&%-XfOw$Q_&DlSvW0X-LCZ~luFGKEXP>u46r!htZ%^sVB!8VGcWH_<=o zOpXHakqa(t>tr${0d5Rij`7vbfVqeRG?de18f^w|J^`W0*F5@R-7A3NpF@4Wn47v# z)MPwznWE?tQTw&Zi<3Eh!5s9FK&ssV?SI~S97CHjEIBIV9x$`~NRmwPJGg<6kqa{h~LQkSHU00;sh@zVh5TJV6W%iZ|Wa>&;(LvU-f(wVk`R5Hla z?V`ZT6|RNrk%3{k6&_KpJb^NcX7(u|0lGa&qU>^E7>qjNu3TYCZE}-p5UN!2D65dI z-j`CimRzw4}wu<)7+ zdsHs0?p{TZxPO{Wv3jCeQ@?9$Q6#~W^thb^FFqaS;eeNI3h}F_$~d1miI#g>NRsp& zm~6l^P>i8n5VeGwsjiPo_l%b}e~DQYG2$gFl|;>IZFzp~j5CW2{@z#b^enNdH9=0rFB9p?9zQOBkB)EgD;{ zR=Hr+x+3|i*YlXOu6j~As}y_mR4VNxnx?DUJ*UejaMYO4=XwE!=xbV$qKe4k$XD02 zLltoBP-+;JGn?!vm-}NbFZ-&XH!P&36QMm%%a*W-#)WO7(4QPTv<@DuUr72~b8GWw zpT;0>6eh;_?J;l#YISD62r~o$kwz!pm_Rpw`c6Rb#BX=^kBaTTC*5l&s8}ydk-j&M zfQ3*Au}f;RZ=q#2YlPWyv(Q1s%KP{bBqB1rPspiQ6vJ!8U3N+zD7O%`o5Mm~pG3`wToui=o+5%*^f_0F2wO1AS^@;UsmJ=}v9 z<}t9BE~uiMUF)~++Ei|A1F23{-CY^Io5(mr%&T1Z~}!Et{CQG`#v zWkQZ#BKNDr_{p|inL^Kp);QO9LEm$6I!FO2Yck1FU4R{yPQ!A}nH23^bCU~3oI94? zP+2o_KTfA1zna)8`jl~i7var?#;Jd)R%S+J2ePeXU4 z&H+DZgehz;qzm2i9cO7B30%+D6q|Fn#uE_|zN*(8Eywy*ll#ZL{mrhvy02m?Oc4Xl|DtE8RdxjEF< zJ0$Npg|dr0E2GT8R;^i_IgHXdb*48d`sVAhI{kXXj)SD)F1Zc1?B~XXDVXfgAr%d2 zD-TWQEvuAdm$s%yiknu9X=LCVvmqT#)}5ouT=RAgwB7hI{;B6LVD}4(kfL$)tYxY! zato5ZTzZ$kgCFNB+Oy2<%fXqHkAWn)EUxk=);-5Xi}5eQ{RwY^g&&EtiJXzFVCKDqx)&5MBaSM*S5s9Ot?$U$}v$K5stY`@pjT^nFMcEwPh?<9@r&P2-UHbH@4YD ztXHuP(Al9?1cxP2Az7Zf9lC|6hzZvbtD~(Kgk!VyFA!f(2Nz;qp=TxSrWJ@Y9hr-1 zv0OykOD7zOJO(AIgOB9y!dM_8W<|m-+9SKGH6O=d3YP8ue=`SkS62G4WRp+3`qpZv zfXBSNe>FM-)bLzAGP5o&icMzntv*J5Jr~fHHZjQ$p`q-S*@?`nsf5U`3+V+DC_2$x$bR>^#_jAbNtNj&Yq8+?2dv>Y)Ur287&!S+6bI#$fq_hi-w$vmNS%9f z=nHWOUGRhH+bc?K!~3q`cH?)Bx8+igYW!!U2{j!Rw#cnrRae;mY3w_r;p)P+M18}mvqZG*z4xa%J7_JgN5*r)3^}J1>TU_dsU22 zZsl0^K9UVE3!C(w7GWW{j_igQcX*}$_50YRNKE3VS*NgGG^{pj-K^2Jias?uovYVg zkcOaVnak6@<0(HkqA0G$h_E<)loNBT2zr)E;-)a>`UTP}l?Nx1_ z#OI<^!lwC#3X_;XJy1U_tG!H*mtP5JSM#Lt!)Y{2fzvu9v6gRayh3UiOc*Lpzj8b|` zR@V+HKjfbpfNxIvB*2b;@vNTs#DN#R62OarDDa|v`{7ZQpNxy?Nby=gxoVr)QL=bI z-H1`W?~LTZBZ5MHyss75p~%&n7lY82md_Fk09v$;9N3WqYVBr_Jf`WC)FcrD&uf^} z-~|6Q{w;)Iz!XMFlqgI)vN{4j@@!PkK6XraBbZQO13`s~=@jRo|p zzIXF4a~Cw;i4f=LQOqVmR1cXCf`m4V)ldDVt49Q zv>S)9TEV`x4WTJeqs?A?+Zbt5{ zd>fVA6Hj1Ou+R#<{o64n0>S(}yM|$Idv6p=-Q^GoEg87kQ6ADVj1aoxZ_0*wkMdAa zl7CiPW_1wZ5NN6w9$dN*G-VjJjQ6|wCs@jh6FNGm`o~1gB_+hI+^3vZev8X28$x0! z(TJ(U6uZm%KXXkKo8rzSIJe`G?!SiNyNx>O6KEaDsUqa&f%1S)XmU|z>-thi)}@hO zRPX9^ojgwn~d% z_pnjb2$w{1q+z;9u+Mv1Aekq8^@}RZJ0*D zESP}~7hlnBMKs+LHb?C<;IK#}UIg-*E19D${QN^OtzbxSc34y{dfy`J)4Y9uVIu3) zd0`K#yAW{o_v=&C(R1wGKR6}PSL69%2v__Hvd*)$UqKN<{`?9ae6bx)EgQ+Vg1}ks z8qM3jTQ$I3T!9FQcKz+}3Xict1Wy{@WRZqmSUz_OCO}xOyDSeMoqoZkMv|sS;w<^Fae4) zRZLk>bBaFs0<@q-(c>5EDv8qA-v|Q&OH>kO-{QhDTyky1^k+bVu0}jp7XOCUF+Ck|a}4lajk=9h#pB8C2dyC0&_}dj6Ovix!T;*HzoZClBR(6XpWu zOuygC3C*{}D91J>OYzId-KyLXi;8GaL=rl94k{9WKkS~ZpS{iHK%xvheS11Bir$}% z=gmWGSR9y&(mUH(x-uJ(Ka%G|w1N)v`xIxmuX*XUtpFxqq5<{Ifi#ErqbwG6J>|)2>L&hbOh&f`9Wt`tg zwg~@FQi#R3;12Dowzs78R($e^l(FZKB}qM7CI5a%u(8l>M9@QTS-lyJZLw_(O)@yn zfBetL;SY5qEVBxQ&EMyc7V|2aVzt~ap{T&P61aQW`p_RzS;h{Yi%kCF%Z|Rw&MY)q1t{e-B7R)m&@>f*A3}X)i}i2$Ma5#&>Mlrfwt?%MdNYhWVm)p?#UNMj3rht zXbLRu^h4w$z%l7+7~|U{D=#gy-O6DQyRxa9Ldi_<&!BD?)FWmEn^rJ&Y4pX5k{%iY z+82|sQgCZCa^|BiebGjhr^2JS$+B_l({jsc4aOv%y%>Cw1WvJ|JPhcPFw;?B#0}bW zt?4em*|j#dvAMjyEaJGfEyKXO|IL@);fE?mq?fA5y@ZH{Mxc0e?uOCGU`OrVcBza# zRDU{qH>tUET5qa}VI{Cp;y^Ag!^~Yu*IU->xanu;hd6DX-tW;Vxdv-bQ>c@c918GC zhv#JEi*`tCMnZWyK7cEh?mle&w#0|S)?uLV!Re-Cls-SyS`&@U5SVK8Jp09k7C%Lm zZ-!=WWPP*~u60Y>f2=rnkRLX314N(ge$8AG7C#sS=`;3W^#9_Jia6g58DBi&3@%Z5 z`vNQtAR^Oa^cucq$)fc&&&p9JolDsnWn)f^97pabuDWpa?%s9Vgk~`Weu&qDS=(Tm z#0?KX5PeM!OGgsLj`5BBv>lT*$Fr~Mb3}@9U;Hn?#hot*sQPW_`gC@bc$9<)Sb*63 zR)7@@A+HOY+~o~+XdgTwZc0tpCG5Iz`&+dl#z=c&&?~oR0F+5nD*!VB5(sjD_qfsC zT(Hd^+%Ce;w1*K@uw?Vo=G}JyMO?&P=#{`lkDP?Ob~yttNu_u1_bs_CV|`kaBw`yg zJgKun#=d!2eaK;aQ_!TZ*55D`b+Wex67^4|egoapW{LiSRy6ud2MJEbagcbj?w!rOeJub zy8=j~EJs-1o7rgh*Dr}alq4dqh&vfJSY>|8i<9#HOER4Vf#{Goy%@vqhdR1OiqpOY zoJ8fR7A6-0pDfSC536dE2kqFlv}vdgG;0N%>oJ2U=8BUart0>g$OU?rL0aPk5F3UC zZZpwK*)@v;l9YP@S8HvGBu+($n zcpNPMl1`qv?w1WY&G1i9gZ9TT&KIXzF7d3_J+7}!Gr?bQ`(reP5vCICIxN!x0xr8H z_A2R$BpA%q$~n7nBI)q{VQb2}weN5h(%lDmInf0HvEL__dad*Klk0MOQ`mA(UEfr} zdkvS2!YlyU*@zUwJNRgnpb59fGubF!>D-Jm^;9@>?t8lOX(}Yc{M}eZ;WVl>RA;#m zLgDoiC<1XBmkV)B-7&OnN=gO`P#INKgzB|J`KQK8!mnt9snH%vlSZ@ivOD}sL0t>^ zd2w@M)=J^5KHNAJQj9kb(WL4~eL?VGo|WzOI>{lk>q5Wo)alxt9Sd*wpsW67t%oT{ z>_s3(&x7j!7r_|Bv?QACr6IfP6}3{=-(}*ps1?@7Ul>#rcb4Oda}cy3_P7uC*`N0p zOXDt7$RDIJU1@|jPE|-u>^4?p9Ej)@%ha>-O4etZ#oH0sFV`nUKV3RSRLOh(!p_i0 zUukF!NKR#~%AQ0K#$D}KW%ApSLn7a;RAQLGC0=ck=J=6oz{|9RuKYNM6gM#_tzQ$Yx>bGz6Gp%*i^IRYirJi>rx zKe%52{p+gGh0l-_6@vDZ4h@bl4?6K!r);B!(?qB@rI8mL@!1yrD&D#9tZ)3&N z@i7I6L?B<`gCM{v;h8sbJ{eedbrzP?8+W;gv5 zsw_Szduy3e_eBlp8^>UnY_)5tLGLRPzJ425wCwMPRs=t3LyC>ouW)0jY)2y|Fp>I$ zWg@{fU3lTnFzZ?E1}hggiNva(rpr!tABotk@_P>!Pjn}ae)%;sZBritd0H{m_xZ5T zP9R+X#g_ppvXQrzHJ*E$+3>-hFEQZG8T}ivw^TnW(%cN#7QIp076Q-`n+|}Yw~|Eq z`)xcfRW;!bq)cPD=~jZ;5zn6>meLj_hchN(`7*rT!AYdY|XDO=5DVv@ zh{GdbOLng6RNe!A6tGNKCWsH^bdE>hwbuh^^OD?HtSJEp@YRsf{Tslv?0={P=rw_M zRvL%Op3Abd6R&yuM39-a1K=xR#hs_F-c^di4p&dgJTjuI`MNIx2-xRleWxwjoldOP zAFra3mE>$kbAFIB3{E^b9Vx)&Iv>pHr@1lG(D$0 z1=qRi88)s+w+JoDXFsA{pq>mce0D)nDPH*uWeC;}~HLTWTQ_aE993Ex)yX;IL>sdjK z%7AS4rpn7i=0=n_tG)T^X6Yg>-gkFOdxq^I>INE}e>gsV$ zPpb={o%YC~uyFvu$wY(~OG)=u+1X1%WE!J*M;^#hH@VW-<|6=}+$gT{jPFW)r1&f+i#GjiN!$v;am#q4qM;) zUeKWO5ru2j_Wr8qKCvhd0v`JJh_h8b$ZXQzGay073M^{?O;~Vvs?$EDw0wkrkL}%1qGD#+StYp)fsO zscg>&eF8rW%zgCCYn^F)**cOHpQ~qprfE7wYR|D(H9ogW>D5CpH+|=${RsmP1{J!U zMA$lty`Cq2QPik&LGN0r5QTbU{t_Y6C9jbI>FtFh9ZY6q5?Acku7t3}DQ%?(hM6U& z=c_&7yy_>|M|*u?y6@NsEqEE0Cu~RO^Om|H{QW~JZ_#$?d;@~W*BDTu z0PmUNF>w;Y@Z*`qsYA2Kj2`O}OmU>&^m(1OQWC?~Xn`0Weg;7kps4V0&S>+_;uzXH zVF5{jR^+_EEr%bEPDYbfF$GWR8)JpH*LC}8+81b?WvTNfb5B}Z3QLD)@7y?fR+RZ? z%7!b^z|hxSegdtl$%Y%>o!bS!Cupymj3ifI1x0iQ9u2bhRN1t4;Q^@H396p~e<+|I}V;G^owr88p!7J0oxkwu6^dNk|NVa((L#!}ur}=Lro~H8{ zx0AkO!E^DeE0wNrwT5u;siL2BT;_5 zCf5l>s&Se=Q?~1s+pQ@P9~2Z#`o68@I`EP5JIq}^V6L;aY=sr@8P4YVVGpMZ61>YZ zeV#DDL$3RW4>v&0d^K99+&jfFfJCYBRkv-`XUu+>5#wS8Jvb<$`w5>Io1*AE-UEs&nG?G&3h_BBYkU+)Y07NkwOj#4F{s+hW}mf@Bv| z)NFrZ;eE~m!BY+Ix%~<=abhGAj(xQMHv@pFKczs1EwvfQU3n~6)7Z{Ir9|d`{nFvu&x*#IebXsA z>5g2VjH}bBd$tLw!$7FM1^~n}7tJ;pm^Wnr zyRPZ;ug64nja)1^oRcfyS1sL@nL(-5KR(}9?VHt#zes^VYc7d@zgk^sJp`ETZl=$v z^m)Gp2c?OYsx-6B+b(u~i^DymD}Tb=)%MShgDGh}+xe{9)V9hMd0ffuPH! zo}{4NsKw(KZ0NO+IS12I4HC6fN(gyS=Bm$~8QMgtG$sFn$9iJn5H0`-`10fQ zdbQrXjw)EPFxX+bPIxkWa5}mBSooSEf&6TfuT}(;U%PQ-=JCK`_@_~0MQ3!IsMTj6 z!J{6|*8eJWNpK0q(uUEziZOHNUD>QGDrw6EAJ+r`h;iD%8JnLd0H8(Kdtdp3DuK0xV{b>2CvNXzzZlt$fd`2CQZy?psB9ZI-Lu8uR&qU~VSG@I`KZl5F=i^uDIi(B#8B zg_Nz$<6eJ2!`}Z)HPYo!q$>N*SG|Dwx^-INS4mZT0D5}ORigcA!ts$HU25eKt8S=} zox*p#c?_P)MP`J6 z3&Pzzh4&PTLlvR3PZtwwn6@u4>!{4L(P#yl>fYu@`xWp%XvZ0jU~{V!uv{9TV!l+Zyr6`$SmWISuWug|Jw4 z!bAG5F@{+cMK#{5-FR+Lj;Ql^F=-odXxOn)M<+&m*y_1c;%~Ll>)+Ep#=6peBrmUk zt5o3Pi$)i(g_|=d2*$D*o(wGGtFPcMppa+TaQipn^liJ zpQ>Y*v6vUUwRJmR^fYAA?a5?8qH;!|lE#U9Mz-ZmN|^rIDD!K>LA{ht$q`{;iR|hb_wI#{ z#R*I48vx%Le6}l?+h!3*ZiL^liYBrDUfVy zl|w^#$;zWt6HUX@zl4?R+x`AIB-FjLF!GruB!tJqrs?v+!t!z5G5*5*AsgY$pwdDb z1lkUxa}m1Glk;_o8ZMx3Y;V%1Pw(@^1i2y;B-MV98NFnAOIIU3=I*%ZtNOWQcW!@X z6Rn_U+}R@x5^)mtEd1zwWIm0+FN+YLs}#iwix_fF_moXTBgvR9``B&-sk&)SNf(Ew zP^5#j8^+~CH?CVif* zu>w@Y4`%Ax4fSgNl9j)K*3)1;k2g6DYPPb|TSvr%SF`GhG2S9Pdyn%jb#LGJI8i0T z6T*q4UFdb=4R+`Zn*|@NR;z^&MFOwVFKS2xlf~k`$F00Ncpc6_(Wzx*QWpclw8fDz zL1_1{-4{hh;^`r(0E~z2QvQo!HxUs?vd9h{0Az1;_lCqjcX`nnCb24)a?d41(}k9# zIfm=rOZQ#f4@N24?D$I?rzhf?Q}jGBwM8ikljJ*_6w#3wQOVlK^9;BNgft*Z)8M%u zRA$KRa3`ScxD>U=L7tJ0LEr(cV5>V}6BD8$SpowoA(ZWFq%D*Prt*)^i5T&Pb!?{7 zdep?yB7QlYdl%Ah^zX(ipQn7b7Qu5|oB+Y`DJ{B`pM{q)&QZQm1^Hn~Vj`iE)?3u( z`m1~lxnqOgkW-Vs*eTKo1w)I5z@BmP$zPz$vc=CGyhD_V9F(rRk0o4j9m6_)GGQ8) zOpY0!Sn@Y*6sdcTIy@VCMyMSs_5_$so6dunfxmw5yOu8Q_~?Jkuiu97(9)+GHT^^IHekhJbGHzRBDVRM?Hw32lE_*Fe#&{-hG-V!Feo zV1e={FMYnir{9Z+&%&h3B8ZR+H#dO<{h?ue+k(^A_ry;F)}JmmB{uP^l!GnEG8yAJ z)$BiS81u;QR0-E^q-W#3;12Qr`xfl@$xK}GM&b%jjWhal(qhHg^Bl`C=NI*?+D$F% zeA_q0?_JS&s%vy_=a2F*RS)3yR^z^dIX(lrFI}x)0PC8gjvew&Iy&AKyn$B<5Oe2x z6i&1oSl}c?Nv}y1#6$BmkK7q@8r*v$vgON-@v1>WWx&Ryx&Zav-VBzu4SLUWCv1` zu|Hnz4@qk`Dsl1adZh0TD!P!%kB5s6gbGg8#zaFm|0?=Vj}w|4$m0GOwmN;|h4`R4 z1_Uqd5r*;4`AW9S4erpPM!0Rqb?vTub3dQ0Zr0@X@e6%fd~gKW<;*q+%--CV*G{=H>nr#lWU5c*z^7V;{95X;f{i8k!De8BEGlp~k@Y}u z)i5eH-Cnn2GNS1n5)~(iukd zLHY6$XNT9eYU+ogoXAW@z_I;D^V(<>w36}umhA+WH;Yq`%n?lY_*UsGF&{r@&wyQOfp_HF0Wm=gwln@RJV!I0}RIiiXl}C||BB`_Z*v#nTMw9m#$@v4SSC{5Ia3K@cDavkyYH ztq@bz653UpxuhZN4qyCQ;7v4bO(@5YL8%X5g=9RqgRc>@k6G+Na3M}dgX0$F5N*tu z+=DA&*f8>O_AAP;3p=*hjyFBn3%P>NmJSMOQb&5=f?ME9Y5Q%#dGNS39>is`0xu@o zML}1_b7t5BmCHGFtzG8(47UTXdht!ayG&eV?ATPCx6QYA@FHWTk~`GQh8^_YiYAm!f`nOU+(iwGUa(S_5`2;KEX=HC;M%dvJDn)F7~mIF;6-GauHTVeTcw(Xlm zOyBju!`qT>J5o(NZ`EdFkj@y<=B=x}-51ayl^llRvDkk>681Gf7D6zHmp~dJEj@*b z*<$Vu^nR`q&as_!!Ru{@DyK&0&rE6Rb(4Y=(mnfif(o0W#)Z@`vtb^mxjuW#5}5YL zkxS+SVC%KaZxW3psC-xGF=R2gt_*{F{X0MYX?_%4Qb%t2s_Mw94R$v z!x!z1K6(7D_ANm8vdtm?(wJ5l%`cM!WM0-WybsN>HdIrx1^(7=9+jmb>Z6YbQ~D{; zUdb9aGvAgKS*tWBIh=T#mWP%8CQgkOYx*#w5Et~-71g4&b6Xqb-zGMp<*-&A;Z}N$ zlxV>t9a6htkvHXXhxnnK6hNy`ThxeYPU%;hBBDMg6c<+eB{gQ9nG}**oLcr zGh_0-TgJStqYp(LGr-I}KA%^XOr8@G#RpYCV0*vv-TR6W7Wi?RUu~%$zS3A7Hn|dn z%fd<{?8bX|9L}605NncuHkx^2vDB=^91|FGmrwWf?mzI#30@*LJ7?>>c4DxoOH{qs z<~){-2+U>Ty=fGirIp|?;_Dlh@-|M)f!8l|yU@nm*L3PDI!f+Oyi~*Gpx1@CPV8mo ze;?^k^S`EzhKJE`T`|1;&U@O=zitDbn^5Dp$R82?8~u~>V5~|toTzsYsUa8q2RTYq zjdBPK)o<%oG&uc-#HE=Y{)TWDm5ZTO#?ZE?Dm@KzjVb=kQ~l)NV|90&vYh~KB;N(@ zHaG0)cQAVLt*DSTB8fHvchjpHN=mFhq*<#Xr4#$Gpn=$Vn|)P z6=yr!G!XWu3i(S7MWiHNUBIJ8b>#*3gUQZgxK8wbAv(UP{UoqByq?SZ?6_LME{@}O z`K=C#?k7gPcHiQ{8q}z^w;cGL;9iBW@w0~T3sMN@TRO}k&*~cG0ZB`Rfk;WdTl3)S zcdqm)(_jNo_@NQAKIIO`_db999>i81MfADl!D99l$8Z1(a-?+@p7Wtd(h}EIJM#!- zGVt;V%%j(qxoyghm9;`Cm@EczYjPq~x0uQ4-^r*{~Q0g$L|H*nInhSt$=wAV9<^ z45%y+DMhn*>??5L?}Cbu(q`IweTkoUyqPgAR$T)G{{^1f7Y~Tq*m*^6u-&&VwjDd> z0qc`vY!s<{MDfG6& zHURJrxPVkTXwY=_-%9!mf7V24qDt{_&j3{8pYu^5gD7@B{&x=iRFtL{67?rF3);Z^ znmlqcN0f8K*X$B!tYu~cFh-D_c6rw~3 z`#7Rep5jgknmef-68N8c0A;!V=M`~= t;^F#F<>E5w49)EL|Ge@4djNis9VEKK@QOJyv+DdI4Kf3x473Xyo|9A=szG zQI&ec(WKCQ_)Qkc`Pn-RJ?lqm+H>|&W zhF);(SVRC5boS5vzR%-KVs+3np0)J@3WMof_>3ju`etby`BTAv2jPz>4pKhfDY|*) z3MY$nz+vake_z<=M+pj^rNgfsV-ZX}wk}od(^kELs0-j?^%?vwV<`17)Ae0k6FPwV z&%bY~(y*t`lTGfivT*NRVs`1P&?0Im&IzvhN;%eSngX}o80CUohlZ+$PAdfr>_Z=j z*hl7mIy{x6oN?z4@QMhV5YJ=Fo5aUYfj6Mv!JP7i{WPsILYWA@1ieQR74Dz;4)RX~ z1cW8C`g<$V5p^pFa#6T>AeHT#(RhOyOgpdIPjdDuzvSr30p*1qRW7B`L9|#0dZzD( zc4mI#R{e^O&F!S8kD*H%M&Zhdc=unC>f|Z=9XZdv8?{ilke%(a$TDIXwtRqF7hr3j zcZZNa%pJaVKFQMb!l_K9?_hMvN&WWCY497$_OcSFvr#d4Mx~2^Rp~iT5?soNsKI1R zhEKM&w7{<#HhLVJ8@LJjfn3*cXPYkZWhkk>zk3zr3yWvUP$o>H5>~TCrx<6qZ=eS> zH=_JFGf-~^m(4VOZq^hdy+nyVb!L|@KSiXqz2bXu@|a!N$S?$2c#9wHFL8)!qigJk z0{+EJ&8B#1OwoOVFe{6Rapb&*{KY&puM$?D+pClQ?SW>d=)r@X(5R%5zgHRu&m=r?m#lhk}c zu8=D%oZrf?5BFqu?0jvM17*Yin&;nZ=qj3G<45`PG9ItwkGM-OOGKmxN=E28D?DUTm>+)T`ro ze*Mb&i$4F0?R@p+Mat{LzdfHc%5SJhx{xw{%`|&M*IEpU=9Fpr2Cna!#ZEko!k04x zm23L0Pb_-p%uX)~6F0^Rh9mAl#jXpmC|-1+ zPSr;Da$eF>MI3N7d&6Un%l=}ao{XMDyAz@K8Y8YalU^Ai7JENPI5-g7I`)-#HCgRo z(o&mKlXt;Eb%Ku5VVhh29SY0%U@Lyn{CfUXmv2%|0;I#gx(8iHn=pWn6C70?uHRSM zQh2Y-(D-*JQkBBtrA}zA2uzk~JIR#$wx2Jx%Zs^vY^-ba3|G7CXoj1vE`K~jfvJn& zyi8$kLN&heI_T55J>aj2w^_Eaa+FY;_flkIC$v<{<0qi>))v22Yj*CBn|COoi_10v z`PMBy_eUaXE~NN<**nBK73PdbaN4h+4vAKSq}5u^cKKKzj$Qfw0v34_i@)<9zvQ#} zbl>?Q)Mkae`1qJNf-6`0ZOgG^PVde{WGlJugvwoy7x2x#AwKt_&?G~N&-X*u3Bfxm zw8f18Xx`CKZ4otH8=n`H%-JM_n!Ve{kuY*|PufW?HeYWEEfrR{ZPf83!g?hMx`fE(pof8qwan`CiyF&GAIEyHW2}#mneEWaOlBRYZ+kgu-q) zQi+MGBterN9j=b{#jm&Ldl{7$3d)jrqO3= z^_Z}C1Kaw-cA#z9U9uKc7&V+yPf3sgvgZ3~}{&8ollC!xgz_+B-x5%nQd z8iylpfL!q4cTUS(-3i`pu8J>LWp0$kn7@mNOqO8R#QYB0AL%21ZMuU6#}M^EPQ!<=<#v}7xwuO-O~K~ujsSlxIAPU>h)C{uP^JB zm!kEjIU`_6n{j&10#laG2dU20Ei!K>q~Z)NoPT0$@EP*9Z19fAv66M0okK4Z^VLNG z`}m`k4hf@!+XEFIXdU~zuI%Ka`rsF965oJWaYsYA!{<~cjy&rv!sPZyf3@Zf6@F3? ztc8nN^R8dZy%wQ5y!8y}IOI5xc`r_YHDac#Ax-zZUbsUX>p<7vdcTzU&ug>9S=EZ= z-FPZ0#hZNqk9bQ{s}`rvDWBsS&CFbIJ650 zvc;8=Et7uL8Ka2FBQC^RKE9t`0=_4YV-NeHs$IeZtecXgvQn�~9@aIi~r<&Q? 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 ?aD{BL|rFN*UvZqWJHPHI$clUWl1~C{8 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 MH@;V{^X%>a0go=koB#j- literal 0 HcmV?d00001 diff --git a/ahk-frontend/brand/BME-AUT logo hungarian/BME_AUT_logo_COLOR_CMYK-hun.eps b/ahk-frontend/brand/BME-AUT logo hungarian/BME_AUT_logo_COLOR_CMYK-hun.eps new file mode 100644 index 0000000000000000000000000000000000000000..86fea0f8170160f9a6d1608bcaffd06b99b28f7f GIT binary patch literal 492938 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 I0?_aO0{Z>g@&Et; literal 0 HcmV?d00001 diff --git a/ahk-frontend/brand/BME-AUT logo hungarian/BME_AUT_logo_COLOR_Pantone202-hun.eps b/ahk-frontend/brand/BME-AUT logo hungarian/BME_AUT_logo_COLOR_Pantone202-hun.eps new file mode 100644 index 0000000000000000000000000000000000000000..7ce06740fb9258413f68277c617c3ccf465cdcaa GIT binary patch literal 492846 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

7u%ili$rjG;UvJZQ#3D<>(eGW9mz*OEc3qN9lB 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

FrSe~&)oLSnbHISt3_?uFhJMXNv#Qup*` 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 literal 0 HcmV?d00001 diff --git a/ahk-frontend/brand/BME-AUT logo hungarian/BME_AUT_logo_WHITE-hun.png b/ahk-frontend/brand/BME-AUT logo hungarian/BME_AUT_logo_WHITE-hun.png new file mode 100644 index 0000000000000000000000000000000000000000..60cb24096df35f12a22b4a7c3d3f235e21dfabb7 GIT binary patch literal 51932 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

E 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 literal 0 HcmV?d00001 diff --git a/ahk-frontend/brand/BME-AUT logo only/BME_AUT_logo_only_COLOR-hun.png b/ahk-frontend/brand/BME-AUT logo only/BME_AUT_logo_only_COLOR-hun.png new file mode 100644 index 0000000000000000000000000000000000000000..05718950d03e96d8faf65e9cbe1ee6fd65d035f3 GIT binary patch literal 31287 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 L-76((HV^*?#=Ow5 literal 0 HcmV?d00001 diff --git a/ahk-frontend/brand/BME-AUT logo only/BME_AUT_logo_only_WHITE-hun.png b/ahk-frontend/brand/BME-AUT logo only/BME_AUT_logo_only_WHITE-hun.png new file mode 100644 index 0000000000000000000000000000000000000000..6c3fedf2e9ace7abfb9c533f958116b91f0e8e1d GIT binary patch literal 31369 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 literal 0 HcmV?d00001 diff --git a/ahk-frontend/brand/README.md b/ahk-frontend/brand/README.md new file mode 100644 index 00000000..d7879a1f --- /dev/null +++ b/ahk-frontend/brand/README.md @@ -0,0 +1,60 @@ +# BME AUT brand assets + +The source assets behind the portal's look: the official **BME AUT** identity pack, and the **eduID** +logo used on the login button. `ahk-frontend` derives its palette and its rendered images from here. + +This folder holds the design masters, which are not shipped. The web-ready copies the app actually +loads live in `../public/` (see the table at the end). + +## What is here + +| Folder | Contents | +|---|---| +| `BME-AUT logo english/` | Full wordmark, "Department of Automation and Applied Informatics" | +| `BME-AUT logo hungarian/` | Full wordmark in Hungarian, plus `TeamsLogo.png` | +| `BME-AUT logo only/` | The `BME /AUT` mark with no wordmark — language-neutral despite the `-hun` suffix | +| `eduID/` | The eduID (Hungarian federation) colour logo, rectangular and square | + +Each wordmark comes in `COLOR`, `BLACK` and `WHITE`, as **PNG** (3645×690, for screen) and **EPS** +(vector print masters, ~480 KB each). The EPS files are the only scalable and re-colourable form — +keep them. `COLOR_CMYK` is for process printing, `COLOR_Pantone202` for spot. + +## Colours + +| Value | What it is | Where it came from | +|---|---|---| +| `#900028` | The logo's own crimson | Exact pixel value sampled from `BME_AUT_logo_COLOR-eng.png` | +| `PANTONE 202 CVC`
CMYK `0 / 1 / 0.6510 / 0.4706` | Print specification of that crimson | `%%CMYKCustomColor` header inside `BME_AUT_logo_COLOR_Pantone202-*.eps` | +| `#a4001e` | Heading + accent crimson used on screen | `h1..h6 { color:#a4001e }` in aut.bme.hu's stylesheet | +| `#88000f` | Active/hover navigation marker | `#mainNavBar a:hover { border-bottom:3px solid #88000f }`, same source | +| `#801b1b` / `#ffcfcf` / `#e5a3a3` | Error text / wash / rule | `.errorBox`, `.critical`, same source | +| `#074371` | Body link navy — **not** crimson | `a[href] { color:#074371 }`, same source | +| `#dbd9c0` | Table-header parchment | `.gridViewHeader`, same source | + +Type on aut.bme.hu: `Georgia, "Times New Roman", Serif` at **normal weight** for every heading, +`Verdana, Arial, Helvetica, sans-serif` for body. + +## eduID + +The login button follows the [eduID brand](https://eduid.hu/hu/depo/). The official button bakes in a +Hungarian label ("Belépés"), so instead of shipping that PNG the login screen renders its own button +from the eduID colour logo plus an English "Login" — the deviation the brand guide permits. Sampled +brand blues: logo `#4070B8` / navy `#203954` / light `#66AADF`; login-button azure `#0068AD`. + +## Using the logo on the web + +`ahk-frontend/public/` holds **derived copies**, not the originals — edit them here and re-copy, do +not edit them there: + +| `ahk-frontend/public/` | Copied from | Used by | +|---|---|---| +| `bme-aut-logo-white.png` | `BME-AUT logo english/BME_AUT_logo_WHITE-eng.png` | Shell topbar (dark band) | +| `bme-aut-logo.png` | `BME-AUT logo english/BME_AUT_logo_COLOR-eng.png` | Login screen (light background) | +| `bme-aut-mark.png` | `BME-AUT logo only/BME_AUT_logo_only_COLOR-hun.png` | Reserved — wordless mark | +| `eduid-logo.png` | `eduID/eduid_logo_color_rect.png` | eduID login button | + +The BME AUT PNGs are 5.28:1, so give them an explicit `height` and `width: auto`, and `alt` text +naming the department. The English wordmark is used because the portal's interface text is English. + +**Known gap**: there is no square favicon. The wordless mark is 2.86:1 and becomes an unreadable +strip at 32px. Producing one needs a square crop from the EPS in a vector editor. diff --git a/ahk-frontend/brand/eduID/eduid_logo_color_rect.png b/ahk-frontend/brand/eduID/eduid_logo_color_rect.png new file mode 100644 index 0000000000000000000000000000000000000000..204648a9ac7a4a0418b1403242f87a136805cfcc GIT binary patch literal 12864 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 literal 0 HcmV?d00001 diff --git a/ahk-frontend/brand/eduID/eduid_logo_color_square.png b/ahk-frontend/brand/eduID/eduid_logo_color_square.png new file mode 100644 index 0000000000000000000000000000000000000000..9554c315ecceeb6253c6fe2a30a59425e1852cca GIT binary patch literal 8477 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 DWPaq` literal 0 HcmV?d00001 diff --git a/ahk-frontend/brand/BME-AUT logo hungarian/BME_AUT_logo_WHITE-hun.eps b/ahk-frontend/brand/BME-AUT logo hungarian/BME_AUT_logo_WHITE-hun.eps new file mode 100644 index 0000000000000000000000000000000000000000..f28a20e8126637f0f3d1a2506e102c94f799c285 GIT binary patch literal 481542 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 literal 0 HcmV?d00001 diff --git a/ahk-frontend/public/bme-aut-mark.png b/ahk-frontend/public/bme-aut-mark.png new file mode 100644 index 0000000000000000000000000000000000000000..05718950d03e96d8faf65e9cbe1ee6fd65d035f3 GIT binary patch literal 31287 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 L-76((HV^*?#=Ow5 literal 0 HcmV?d00001 diff --git a/ahk-frontend/public/eduid-logo.png b/ahk-frontend/public/eduid-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..204648a9ac7a4a0418b1403242f87a136805cfcc GIT binary patch literal 12864 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 literal 0 HcmV?d00001 diff --git a/ahk-frontend/src/app/api/api-client.ts b/ahk-frontend/src/app/api/api-client.ts index 9cde2fb3..51d95033 100644 --- a/ahk-frontend/src/app/api/api-client.ts +++ b/ahk-frontend/src/app/api/api-client.ts @@ -14,15 +14,15 @@ import { HttpClient, HttpHeaders, HttpResponse, HttpResponseBase } from '@angula export const API_BASE_URL = new InjectionToken('API_BASE_URL'); -export interface ICourseProbeClient { - getNotes(course: string): Observable; - addNote(request: CreateCourseNoteRequest, course: string): Observable; +export interface IGradesClient { + list(course: string): Observable; + exportCsv(course: string): Observable; } @Injectable({ providedIn: 'root' }) -export class CourseProbeClient implements ICourseProbeClient { +export class GradesClient implements IGradesClient { private http: HttpClient; private baseUrl: string; protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; @@ -32,8 +32,8 @@ export class CourseProbeClient implements ICourseProbeClient { this.baseUrl = baseUrl ?? "https://localhost:7443"; } - getNotes(course: string): Observable { - let url_ = this.baseUrl + "/api/{course}/probe/notes"; + list(course: string): Observable { + let url_ = this.baseUrl + "/api/{course}/grades"; if (course === undefined || course === null) throw new globalThis.Error("The parameter 'course' must be defined."); url_ = url_.replace("{course}", encodeURIComponent("" + course)); @@ -49,20 +49,20 @@ export class CourseProbeClient implements ICourseProbeClient { }; return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { - return this.processGetNotes(response_); + return this.processList(response_); })).pipe(_observableCatch((response_: any) => { if (response_ instanceof HttpResponseBase) { try { - return this.processGetNotes(response_ as any); + return this.processList(response_ as any); } catch (e) { - return _observableThrow(e) as any as Observable; + return _observableThrow(e) as any as Observable; } } else - return _observableThrow(response_) as any as Observable; + return _observableThrow(response_) as any as Observable; })); } - protected processGetNotes(response: HttpResponseBase): Observable { + protected processList(response: HttpResponseBase): Observable { const status = response.status; const responseBlob = response instanceof HttpResponse ? response.body : @@ -72,7 +72,7 @@ export class CourseProbeClient implements ICourseProbeClient { if (status === 200) { return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { let result200: any = null; - result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as CourseNoteDto[]; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as FinalStudentGrade[]; return _observableOf(result200); })); } else if (status !== 200 && status !== 204) { @@ -83,41 +83,106 @@ export class CourseProbeClient implements ICourseProbeClient { return _observableOf(null as any); } - addNote(request: CreateCourseNoteRequest, course: string): Observable { - let url_ = this.baseUrl + "/api/{course}/probe/notes"; + exportCsv(course: string): Observable { + let url_ = this.baseUrl + "/api/{course}/grades/csv"; if (course === undefined || course === null) throw new globalThis.Error("The parameter 'course' must be defined."); url_ = url_.replace("{course}", encodeURIComponent("" + course)); url_ = url_.replace(/[?&]$/, ""); - const content_ = JSON.stringify(request); + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processExportCsv(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processExportCsv(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processExportCsv(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as string; + return _observableOf(result200); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } +} + +export interface ISubmissionStatusesClient { + list(course: string): Observable; +} + +@Injectable({ + providedIn: 'root' +}) +export class SubmissionStatusesClient implements ISubmissionStatusesClient { + private http: HttpClient; + private baseUrl: string; + protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; + + constructor(@Inject(HttpClient) http: HttpClient, @Optional() @Inject(API_BASE_URL) baseUrl?: string) { + this.http = http; + this.baseUrl = baseUrl ?? "https://localhost:7443"; + } + + list(course: string): Observable { + let url_ = this.baseUrl + "/api/{course}/statuses"; + if (course === undefined || course === null) + throw new globalThis.Error("The parameter 'course' must be defined."); + url_ = url_.replace("{course}", encodeURIComponent("" + course)); + url_ = url_.replace(/[?&]$/, ""); let options_ : any = { - body: content_, observe: "response", responseType: "blob", withCredentials: true, headers: new HttpHeaders({ - "Content-Type": "application/json", "Accept": "application/json" }) }; - return this.http.request("post", url_, options_).pipe(_observableMergeMap((response_ : any) => { - return this.processAddNote(response_); + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processList(response_); })).pipe(_observableCatch((response_: any) => { if (response_ instanceof HttpResponseBase) { try { - return this.processAddNote(response_ as any); + return this.processList(response_ as any); } catch (e) { - return _observableThrow(e) as any as Observable; + return _observableThrow(e) as any as Observable; } } else - return _observableThrow(response_) as any as Observable; + return _observableThrow(response_) as any as Observable; })); } - protected processAddNote(response: HttpResponseBase): Observable { + protected processList(response: HttpResponseBase): Observable { const status = response.status; const responseBlob = response instanceof HttpResponse ? response.body : @@ -127,7 +192,7 @@ export class CourseProbeClient implements ICourseProbeClient { if (status === 200) { return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { let result200: any = null; - result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as CourseNoteDto; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as RepositoryStatus[]; return _observableOf(result200); })); } else if (status !== 200 && status !== 204) { @@ -141,7 +206,7 @@ export class CourseProbeClient implements ICourseProbeClient { export interface IAuthClient { login(request: LoginRequest): Observable; - logout(): Observable; + logout(): Observable; register(request: RegisterRequest): Observable; me(): Observable; } @@ -206,7 +271,7 @@ export class AuthClient implements IAuthClient { } else if (status === 401) { return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { let result401: any = null; - result401 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + result401 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as LoginFailureResponse; return throwException("A server side error occurred.", status, _responseText, _headers, result401); })); } else if (status !== 200 && status !== 204) { @@ -217,7 +282,7 @@ export class AuthClient implements IAuthClient { return _observableOf(null as any); } - logout(): Observable { + logout(): Observable { let url_ = this.baseUrl + "/api/auth/logout"; url_ = url_.replace(/[?&]$/, ""); @@ -226,6 +291,7 @@ export class AuthClient implements IAuthClient { responseType: "blob", withCredentials: true, headers: new HttpHeaders({ + "Accept": "application/json" }) }; @@ -236,23 +302,25 @@ export class AuthClient implements IAuthClient { try { return this.processLogout(response_ as any); } catch (e) { - return _observableThrow(e) as any as Observable; + return _observableThrow(e) as any as Observable; } } else - return _observableThrow(response_) as any as Observable; + return _observableThrow(response_) as any as Observable; })); } - protected processLogout(response: HttpResponseBase): Observable { + protected processLogout(response: HttpResponseBase): Observable { const status = response.status; const responseBlob = response instanceof HttpResponse ? response.body : (response as any).error instanceof Blob ? (response as any).error : undefined; let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} - if (status === 204) { + if (status === 200) { return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { - return _observableOf(null as any); + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as LogoutResponse; + return _observableOf(result200); })); } else if (status !== 200 && status !== 204) { return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { @@ -378,6 +446,7 @@ export class AuthClient implements IAuthClient { export interface IExternalAuthClient { challenge(returnUrl?: string | null | undefined): Observable; callback(returnUrl?: string | null | undefined): Observable; + signedOut(returnUrl?: string | null | undefined): Observable; } @Injectable({ @@ -502,12 +571,201 @@ export class ExternalAuthClient implements IExternalAuthClient { } return _observableOf(null as any); } + + signedOut(returnUrl?: string | null | undefined): Observable { + let url_ = this.baseUrl + "/signout-callback-oidc?"; + if (returnUrl !== undefined && returnUrl !== null) + url_ += "returnUrl=" + encodeURIComponent("" + returnUrl) + "&"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/octet-stream" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processSignedOut(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processSignedOut(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processSignedOut(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200 || status === 206) { + const contentDisposition = response.headers ? response.headers.get("content-disposition") : undefined; + let fileNameMatch = contentDisposition ? /filename\*=(?:(\\?['"])(.*?)\1|(?:[^\s]+'.*?')?([^;\n]*))/g.exec(contentDisposition) : undefined; + let fileName = fileNameMatch && fileNameMatch.length > 1 ? fileNameMatch[3] || fileNameMatch[2] : undefined; + if (fileName) { + fileName = decodeURIComponent(fileName); + } else { + fileNameMatch = contentDisposition ? /filename="?([^"]*?)"?(;|$)/g.exec(contentDisposition) : undefined; + fileName = fileNameMatch && fileNameMatch.length > 1 ? fileNameMatch[1] : undefined; + } + return _observableOf({ fileName: fileName, data: responseBlob as any, status: status, headers: _headers }); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } +} + +export interface ICourseHealthAdminClient { + checkAll(): Observable; + checkCourse(courseId: number): Observable; +} + +@Injectable({ + providedIn: 'root' +}) +export class CourseHealthAdminClient implements ICourseHealthAdminClient { + private http: HttpClient; + private baseUrl: string; + protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; + + constructor(@Inject(HttpClient) http: HttpClient, @Optional() @Inject(API_BASE_URL) baseUrl?: string) { + this.http = http; + this.baseUrl = baseUrl ?? "https://localhost:7443"; + } + + checkAll(): Observable { + let url_ = this.baseUrl + "/api/admin/health"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processCheckAll(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processCheckAll(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processCheckAll(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as CourseHealthReport[]; + return _observableOf(result200); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + checkCourse(courseId: number): Observable { + let url_ = this.baseUrl + "/api/admin/health/{courseId}"; + if (courseId === undefined || courseId === null) + throw new globalThis.Error("The parameter 'courseId' must be defined."); + url_ = url_.replace("{courseId}", encodeURIComponent("" + courseId)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processCheckCourse(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processCheckCourse(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processCheckCourse(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as CourseHealthReport; + return _observableOf(result200); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } } export interface ICoursesAdminClient { list(): Observable; - create(request: CreateCourseRequest): Observable; - get(id: string): Observable; + create(request: CreateCourseRequest): Observable; + get(id: number): Observable; + update(id: number, request: UpdateCourseRequest): Observable; + delete(id: number, confirmSlug?: string | null | undefined): Observable; + getGitHubConfig(id: number): Observable; + updateGitHubConfig(id: number, request: UpdateCourseGitHubConfigRequest): Observable; + listMembers(id: number): Observable; + upsertMember(id: number, request: UpsertCourseMemberRequest): Observable; + removeMember(id: number, userId: number): Observable; + listTokens(id: number): Observable; + createToken(id: number, request: CreateWebhookTokenRequest): Observable; + revokeToken(id: number, tokenId: number): Observable; } @Injectable({ @@ -571,7 +829,7 @@ export class CoursesAdminClient implements ICoursesAdminClient { return _observableOf(null as any); } - create(request: CreateCourseRequest): Observable { + create(request: CreateCourseRequest): Observable { let url_ = this.baseUrl + "/api/admin/courses"; url_ = url_.replace(/[?&]$/, ""); @@ -595,14 +853,14 @@ export class CoursesAdminClient implements ICoursesAdminClient { try { return this.processCreate(response_ as any); } catch (e) { - return _observableThrow(e) as any as Observable; + return _observableThrow(e) as any as Observable; } } else - return _observableThrow(response_) as any as Observable; + return _observableThrow(response_) as any as Observable; })); } - protected processCreate(response: HttpResponseBase): Observable { + protected processCreate(response: HttpResponseBase): Observable { const status = response.status; const responseBlob = response instanceof HttpResponse ? response.body : @@ -612,7 +870,7 @@ export class CoursesAdminClient implements ICoursesAdminClient { if (status === 201) { return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { let result201: any = null; - result201 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as CourseDto; + result201 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as CourseDetailDto; return _observableOf(result201); })); } else if (status === 409) { @@ -629,7 +887,7 @@ export class CoursesAdminClient implements ICoursesAdminClient { return _observableOf(null as any); } - get(id: string): Observable { + get(id: number): Observable { let url_ = this.baseUrl + "/api/admin/courses/{id}"; if (id === undefined || id === null) throw new globalThis.Error("The parameter 'id' must be defined."); @@ -652,14 +910,14 @@ export class CoursesAdminClient implements ICoursesAdminClient { try { return this.processGet(response_ as any); } catch (e) { - return _observableThrow(e) as any as Observable; + return _observableThrow(e) as any as Observable; } } else - return _observableThrow(response_) as any as Observable; + return _observableThrow(response_) as any as Observable; })); } - protected processGet(response: HttpResponseBase): Observable { + protected processGet(response: HttpResponseBase): Observable { const status = response.status; const responseBlob = response instanceof HttpResponse ? response.body : @@ -669,7 +927,7 @@ export class CoursesAdminClient implements ICoursesAdminClient { if (status === 200) { return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { let result200: any = null; - result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as CourseDto; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as CourseDetailDto; return _observableOf(result200); })); } else if (status === 404) { @@ -685,31 +943,1223 @@ export class CoursesAdminClient implements ICoursesAdminClient { } return _observableOf(null as any); } -} -export interface CourseNoteDto { - id?: string; - text?: string; - createdAt?: Date; -} + update(id: number, request: UpdateCourseRequest): Observable { + let url_ = this.baseUrl + "/api/admin/courses/{id}"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); -export interface CreateCourseNoteRequest { - text?: string; -} + const content_ = JSON.stringify(request); -export interface CurrentUserResponse { - userId?: string; - userName?: string; - email?: string | undefined; - displayName?: string | undefined; - roles?: string[]; - courses?: CourseMembershipDto[]; -} + let options_ : any = { + body: content_, + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Content-Type": "application/json", + }) + }; -export interface CourseMembershipDto { - slug?: string; - name?: string; - role?: string; + return this.http.request("put", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processUpdate(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processUpdate(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processUpdate(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return _observableOf(null as any); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status === 409) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result409: any = null; + result409 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result409); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + delete(id: number, confirmSlug?: string | null | undefined): Observable { + let url_ = this.baseUrl + "/api/admin/courses/{id}?"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + if (confirmSlug !== undefined && confirmSlug !== null) + url_ += "confirmSlug=" + encodeURIComponent("" + confirmSlug) + "&"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + }) + }; + + return this.http.request("delete", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processDelete(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processDelete(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processDelete(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return _observableOf(null as any); + })); + } else if (status === 400) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result400: any = null; + result400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result400); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + getGitHubConfig(id: number): Observable { + let url_ = this.baseUrl + "/api/admin/courses/{id}/github"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processGetGitHubConfig(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processGetGitHubConfig(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processGetGitHubConfig(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as CourseGitHubConfigDto; + return _observableOf(result200); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + updateGitHubConfig(id: number, request: UpdateCourseGitHubConfigRequest): Observable { + let url_ = this.baseUrl + "/api/admin/courses/{id}/github"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(request); + + let options_ : any = { + body: content_, + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Content-Type": "application/json", + "Accept": "application/json" + }) + }; + + return this.http.request("put", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processUpdateGitHubConfig(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processUpdateGitHubConfig(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processUpdateGitHubConfig(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as CourseGitHubConfigDto; + return _observableOf(result200); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + listMembers(id: number): Observable { + let url_ = this.baseUrl + "/api/admin/courses/{id}/members"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processListMembers(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processListMembers(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processListMembers(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as CourseMemberDto[]; + return _observableOf(result200); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + upsertMember(id: number, request: UpsertCourseMemberRequest): Observable { + let url_ = this.baseUrl + "/api/admin/courses/{id}/members"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(request); + + let options_ : any = { + body: content_, + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Content-Type": "application/json", + }) + }; + + return this.http.request("put", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processUpsertMember(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processUpsertMember(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processUpsertMember(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return _observableOf(null as any); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + removeMember(id: number, userId: number): Observable { + let url_ = this.baseUrl + "/api/admin/courses/{id}/members/{userId}"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + if (userId === undefined || userId === null) + throw new globalThis.Error("The parameter 'userId' must be defined."); + url_ = url_.replace("{userId}", encodeURIComponent("" + userId)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + }) + }; + + return this.http.request("delete", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processRemoveMember(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processRemoveMember(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processRemoveMember(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return _observableOf(null as any); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + listTokens(id: number): Observable { + let url_ = this.baseUrl + "/api/admin/courses/{id}/tokens"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processListTokens(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processListTokens(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processListTokens(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as WebhookTokenDto[]; + return _observableOf(result200); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + createToken(id: number, request: CreateWebhookTokenRequest): Observable { + let url_ = this.baseUrl + "/api/admin/courses/{id}/tokens"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(request); + + let options_ : any = { + body: content_, + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Content-Type": "application/json", + "Accept": "application/json" + }) + }; + + return this.http.request("post", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processCreateToken(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processCreateToken(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processCreateToken(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 201) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result201: any = null; + result201 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as WebhookTokenDto; + return _observableOf(result201); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + revokeToken(id: number, tokenId: number): Observable { + let url_ = this.baseUrl + "/api/admin/courses/{id}/tokens/{tokenId}"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + if (tokenId === undefined || tokenId === null) + throw new globalThis.Error("The parameter 'tokenId' must be defined."); + url_ = url_.replace("{tokenId}", encodeURIComponent("" + tokenId)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + }) + }; + + return this.http.request("delete", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processRevokeToken(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processRevokeToken(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processRevokeToken(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return _observableOf(null as any); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } +} + +export interface IUsersAdminClient { + list(search?: string | null | undefined, courseId?: number | null | undefined, skip?: number | undefined, take?: number | undefined): Observable; + create(request: CreateUserRequest): Observable; + get(id: number): Observable; + update(id: number, request: UpdateUserRequest): Observable; + delete(id: number): Observable; + updateRoles(id: number, request: UpdateUserRolesRequest): Observable; + upsertCourse(id: number, request: UpsertUserCourseRequest): Observable; + removeCourse(id: number, courseId: number): Observable; + setPassword(id: number, request: SetPasswordRequest): Observable; +} + +@Injectable({ + providedIn: 'root' +}) +export class UsersAdminClient implements IUsersAdminClient { + private http: HttpClient; + private baseUrl: string; + protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; + + constructor(@Inject(HttpClient) http: HttpClient, @Optional() @Inject(API_BASE_URL) baseUrl?: string) { + this.http = http; + this.baseUrl = baseUrl ?? "https://localhost:7443"; + } + + list(search?: string | null | undefined, courseId?: number | null | undefined, skip?: number | undefined, take?: number | undefined): Observable { + let url_ = this.baseUrl + "/api/admin/users?"; + if (search !== undefined && search !== null) + url_ += "search=" + encodeURIComponent("" + search) + "&"; + if (courseId !== undefined && courseId !== null) + url_ += "courseId=" + encodeURIComponent("" + courseId) + "&"; + if (skip === null) + throw new globalThis.Error("The parameter 'skip' cannot be null."); + else if (skip !== undefined) + url_ += "skip=" + encodeURIComponent("" + skip) + "&"; + if (take === null) + throw new globalThis.Error("The parameter 'take' cannot be null."); + else if (take !== undefined) + url_ += "take=" + encodeURIComponent("" + take) + "&"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processList(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processList(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processList(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as UserListResponse; + return _observableOf(result200); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + create(request: CreateUserRequest): Observable { + let url_ = this.baseUrl + "/api/admin/users"; + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(request); + + let options_ : any = { + body: content_, + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Content-Type": "application/json", + "Accept": "application/json" + }) + }; + + return this.http.request("post", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processCreate(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processCreate(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processCreate(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 201) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result201: any = null; + result201 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as UserDto; + return _observableOf(result201); + })); + } else if (status === 400) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result400: any = null; + result400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result400); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + get(id: number): Observable { + let url_ = this.baseUrl + "/api/admin/users/{id}"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processGet(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processGet(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processGet(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as UserDto; + return _observableOf(result200); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + update(id: number, request: UpdateUserRequest): Observable { + let url_ = this.baseUrl + "/api/admin/users/{id}"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(request); + + let options_ : any = { + body: content_, + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Content-Type": "application/json", + "Accept": "application/json" + }) + }; + + return this.http.request("put", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processUpdate(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processUpdate(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processUpdate(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as UserDto; + return _observableOf(result200); + })); + } else if (status === 400) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result400: any = null; + result400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result400); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + delete(id: number): Observable { + let url_ = this.baseUrl + "/api/admin/users/{id}"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + }) + }; + + return this.http.request("delete", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processDelete(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processDelete(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processDelete(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return _observableOf(null as any); + })); + } else if (status === 400) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result400: any = null; + result400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result400); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + updateRoles(id: number, request: UpdateUserRolesRequest): Observable { + let url_ = this.baseUrl + "/api/admin/users/{id}/roles"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(request); + + let options_ : any = { + body: content_, + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Content-Type": "application/json", + "Accept": "application/json" + }) + }; + + return this.http.request("put", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processUpdateRoles(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processUpdateRoles(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processUpdateRoles(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as UserDto; + return _observableOf(result200); + })); + } else if (status === 400) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result400: any = null; + result400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result400); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + upsertCourse(id: number, request: UpsertUserCourseRequest): Observable { + let url_ = this.baseUrl + "/api/admin/users/{id}/courses"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(request); + + let options_ : any = { + body: content_, + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Content-Type": "application/json", + "Accept": "application/json" + }) + }; + + return this.http.request("put", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processUpsertCourse(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processUpsertCourse(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processUpsertCourse(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as UserDto; + return _observableOf(result200); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + removeCourse(id: number, courseId: number): Observable { + let url_ = this.baseUrl + "/api/admin/users/{id}/courses/{courseId}"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + if (courseId === undefined || courseId === null) + throw new globalThis.Error("The parameter 'courseId' must be defined."); + url_ = url_.replace("{courseId}", encodeURIComponent("" + courseId)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("delete", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processRemoveCourse(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processRemoveCourse(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processRemoveCourse(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as UserDto; + return _observableOf(result200); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + setPassword(id: number, request: SetPasswordRequest): Observable { + let url_ = this.baseUrl + "/api/admin/users/{id}/password"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(request); + + let options_ : any = { + body: content_, + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Content-Type": "application/json", + }) + }; + + return this.http.request("post", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processSetPassword(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processSetPassword(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processSetPassword(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return _observableOf(null as any); + })); + } else if (status === 400) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result400: any = null; + result400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result400); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } +} + +export interface FinalStudentGrade { + neptun?: string; + repo?: string; + prUrl?: string | undefined; + points?: { [key: string]: number; }; +} + +export interface RepositoryStatus { + repository?: string; + neptun?: string; + branches?: string[]; + pullRequests?: PullRequestStatus[]; + workflowRuns?: WorkflowRunsStatus; +} + +export interface PullRequestStatus { + number?: number; + htmlUrl?: string | undefined; + status?: string | undefined; + assignee?: string | undefined; +} + +export interface WorkflowRunsStatus { + count?: number; + lastStatus?: string | undefined; +} + +export interface CurrentUserResponse { + userId?: number; + userName?: string; + email?: string | undefined; + displayName?: string | undefined; + roles?: string[]; + courses?: CourseMembershipDto[]; +} + +export interface CourseMembershipDto { + slug?: string; + name?: string; + role?: string; + viaSiteAdmin?: boolean; +} + +export interface LoginFailureResponse { + reason?: string; + error?: string; +} + +export interface LoginRequest { + userName: string; + password: string; + rememberMe?: boolean; +} + +export interface LogoutResponse { + endSessionUrl?: string | undefined; } export interface ProblemDetails { @@ -722,12 +2172,6 @@ export interface ProblemDetails { [key: string]: any; } -export interface LoginRequest { - userName: string; - password: string; - rememberMe?: boolean; -} - export interface RegisterRequest { userName: string; email: string; @@ -735,18 +2179,164 @@ export interface RegisterRequest { displayName?: string | undefined; } +export interface CourseHealthReport { + courseId?: number; + courseSlug?: string; + courseName?: string; + checkedAt?: Date; + checks?: HealthCheckResult[]; + status?: HealthStatus; +} + +export interface HealthCheckResult { + checkId?: string; + title?: string; + status?: HealthStatus; + message?: string; + remediation?: string | undefined; + durationMs?: number; +} + +export type HealthStatus = "NotConfigured" | "Healthy" | "Warning" | "Failed"; + export interface CourseDto { - id?: string; + id?: number; + slug?: string; + name?: string; + gitHubOrganization?: string | undefined; + repoNamePrefix?: string | undefined; + createdAt?: Date; + integrationEnabled?: boolean; + memberCount?: number; + studentCount?: number; + submissionCount?: number; +} + +export interface CourseDetailDto { + id?: number; slug?: string; name?: string; gitHubOrganization?: string | undefined; + repoNamePrefix?: string | undefined; + createdAt?: Date; + studentCount?: number; + submissionCount?: number; + gitHubConfig?: CourseGitHubConfigDto; + members?: CourseMemberDto[]; + webhookTokens?: WebhookTokenDto[]; +} + +export interface CourseGitHubConfigDto { + gitHubAppId?: string | undefined; + hasAppPrivateKey?: boolean; + hasAccessToken?: boolean; + accessTokenHint?: string | undefined; + hasWebhookSecret?: boolean; + workflowRunThreshold?: number; + enabled?: boolean; + updatedAt?: Date | undefined; +} + +export interface CourseMemberDto { + userId?: number; + userName?: string; + displayName?: string | undefined; + email?: string | undefined; + role?: CourseRole; +} + +export type CourseRole = "Instructor" | "Admin"; + +export interface WebhookTokenDto { + id?: number; + token?: string; + secret?: string | undefined; + description?: string | undefined; createdAt?: Date; + revokedAt?: Date | undefined; } export interface CreateCourseRequest { slug: string; name: string; gitHubOrganization?: string | undefined; + repoNamePrefix?: string | undefined; +} + +export interface UpdateCourseRequest { + slug: string; + name: string; + gitHubOrganization?: string | undefined; + repoNamePrefix?: string | undefined; +} + +export interface UpdateCourseGitHubConfigRequest { + gitHubAppId?: string | undefined; + gitHubAppPrivateKey?: string | undefined; + gitHubAccessToken?: string | undefined; + gitHubWebhookSecret?: string | undefined; + workflowRunThreshold?: number; + enabled?: boolean; +} + +export interface UpsertCourseMemberRequest { + userId: number; + role?: CourseRole; +} + +export interface CreateWebhookTokenRequest { + description?: string | undefined; +} + +export interface UserListResponse { + items?: UserDto[]; + total?: number; +} + +export interface UserDto { + id?: number; + userName?: string; + email?: string | undefined; + displayName?: string | undefined; + neptunCode?: string | undefined; + affiliation?: string | undefined; + roles?: string[]; + courses?: UserCourseDto[]; + isExternal?: boolean; + isLockedOut?: boolean; +} + +export interface UserCourseDto { + courseId?: number; + slug?: string; + name?: string; + role?: CourseRole; +} + +export interface CreateUserRequest { + userName: string; + email?: string | undefined; + displayName?: string | undefined; + password: string; +} + +export interface UpdateUserRequest { + email?: string | undefined; + displayName?: string | undefined; + neptunCode?: string | undefined; +} + +export interface UpdateUserRolesRequest { + roles?: string[]; +} + +export interface UpsertUserCourseRequest { + courseId: number; + role?: CourseRole; +} + +export interface SetPasswordRequest { + newPassword: string; } export interface FileResponse { diff --git a/ahk-frontend/src/app/app.routes.ts b/ahk-frontend/src/app/app.routes.ts index a4129b10..0482f054 100644 --- a/ahk-frontend/src/app/app.routes.ts +++ b/ahk-frontend/src/app/app.routes.ts @@ -1,6 +1,6 @@ import { Routes } from '@angular/router'; -import { authGuard, adminGuard } from './core/auth/auth.guard'; +import { adminGuard, authGuard, rootRedirectGuard } from './core/auth/auth.guard'; import { courseGuard } from './core/course/course.guard'; import { Shell } from './layout/shell/shell'; @@ -9,6 +9,13 @@ export const routes: Routes = [ path: 'login', loadComponent: () => import('./features/login/login').then((m) => m.Login), }, + { + // Signed in, but assigned to nothing yet. Without this the guards would bounce such a user back to the + // login screen they just came from, with no explanation. + path: 'no-access', + canActivate: [authGuard], + loadComponent: () => import('./features/no-access/no-access').then((m) => m.NoAccess), + }, { // Host/admin context (no course segment). path: 'admin', @@ -19,6 +26,18 @@ export const routes: Routes = [ path: 'courses', loadComponent: () => import('./features/admin/courses/courses').then((m) => m.AdminCourses), }, + { + path: 'courses/:id', + loadComponent: () => import('./features/admin/courses/course-editor').then((m) => m.CourseEditor), + }, + { + path: 'users', + loadComponent: () => import('./features/admin/users/users').then((m) => m.AdminUsers), + }, + { + path: 'health', + loadComponent: () => import('./features/admin/health/health').then((m) => m.AdminHealth), + }, { path: '', pathMatch: 'full', redirectTo: 'courses' }, ], }, @@ -35,6 +54,8 @@ export const routes: Routes = [ { path: '', pathMatch: 'full', redirectTo: 'dashboard' }, ], }, - { path: '', pathMatch: 'full', redirectTo: 'login' }, - { path: '**', redirectTo: 'login' }, + // "/" resolves per user rather than always going to the login form: the OIDC callback lands here when it + // has no return URL, and by then the session already exists. + { path: '', pathMatch: 'full', canActivate: [rootRedirectGuard], children: [] }, + { path: '**', redirectTo: '' }, ]; diff --git a/ahk-frontend/src/app/core/api-error.ts b/ahk-frontend/src/app/core/api-error.ts new file mode 100644 index 00000000..3adc9cc4 --- /dev/null +++ b/ahk-frontend/src/app/core/api-error.ts @@ -0,0 +1,34 @@ +/** + * Turns a failed generated-client call into a sentence worth showing. + * + * The NSwag clients throw a `SwaggerException` carrying the raw response body, so the API's own message — + * `{ "error": … }`, `{ "errors": [ … ] }` or a ProblemDetails `title` — has to be dug out. Status 0 is the + * case that matters most in development: it means the request never reached the backend, and reporting that + * as "wrong password" or "could not save" sends people looking in the wrong place. + */ +export function readApiError(error: unknown, fallback: string): string { + const status = (error as { status?: number }).status; + + if (status === 0) { + return 'The server is not responding. Check that the backend is running, then try again.'; + } + + const body = (error as { response?: string }).response; + if (body) { + try { + const parsed = JSON.parse(body) as { error?: string; errors?: string[]; title?: string; detail?: string }; + const message = parsed.error ?? parsed.errors?.join(' ') ?? parsed.detail ?? parsed.title; + if (message) { + return message; + } + } catch { + // Not JSON — fall through to the caller's wording. + } + } + + if (status === 403) { + return 'You do not have access to do that.'; + } + + return fallback; +} diff --git a/ahk-frontend/src/app/core/auth/auth.guard.ts b/ahk-frontend/src/app/core/auth/auth.guard.ts index 98cc52ba..3b87f07c 100644 --- a/ahk-frontend/src/app/core/auth/auth.guard.ts +++ b/ahk-frontend/src/app/core/auth/auth.guard.ts @@ -2,6 +2,7 @@ import { inject } from '@angular/core'; import { CanActivateFn, Router } from '@angular/router'; import { map } from 'rxjs/operators'; +import { CourseContextService } from '../course/course-context.service'; import { AuthService } from './auth.service'; /** Requires an authenticated session; otherwise redirects to /login preserving the target URL. */ @@ -13,9 +14,32 @@ export const authGuard: CanActivateFn = (_route, state) => { ); }; -/** Requires the site-admin role; otherwise sends the user to their default landing. */ +/** + * Sends "/" to wherever this particular user belongs. This is also where the OIDC callback lands when it has + * no return URL to honour, so it has to work for a session that was established outside the SPA. + */ +export const rootRedirectGuard: CanActivateFn = () => { + const auth = inject(AuthService); + const router = inject(Router); + return auth.ensureLoaded().pipe(map((user) => router.createUrlTree([user ? auth.landingUrl() : '/login']))); +}; + +/** + * Requires the site-admin role. Also clears the course context: the site screens have no course, and the shell + * picks which rail to show from it. + */ export const adminGuard: CanActivateFn = () => { const auth = inject(AuthService); + const courseContext = inject(CourseContextService); const router = inject(Router); - return auth.ensureLoaded().pipe(map(() => (auth.isAdmin() ? true : router.createUrlTree(['/login'])))); + + return auth.ensureLoaded().pipe( + map(() => { + if (!auth.isAdmin()) { + return router.createUrlTree([auth.landingUrl()]); + } + courseContext.setActiveSlug(null); + return true; + }), + ); }; diff --git a/ahk-frontend/src/app/core/auth/auth.service.ts b/ahk-frontend/src/app/core/auth/auth.service.ts index 71da58fb..4e608d73 100644 --- a/ahk-frontend/src/app/core/auth/auth.service.ts +++ b/ahk-frontend/src/app/core/auth/auth.service.ts @@ -3,6 +3,7 @@ import { Observable, of } from 'rxjs'; import { catchError, map, tap } from 'rxjs/operators'; import { AuthClient, CurrentUserResponse, LoginRequest } from '../../api/api-client'; +import { readApiError } from '../api-error'; /** * Session state for the SPA. Hydrates from GET /api/auth/me (cookie-based), exposes the current user and @@ -18,6 +19,11 @@ export class AuthService { readonly currentUser = this.user.asReadonly(); readonly isAuthenticated = computed(() => this.user() !== null); readonly isAdmin = computed(() => this.user()?.roles?.includes('Admin') ?? false); + + /** + * Every course this user can open. The API already folds a site admin's implicit access into this list, so + * the course switcher and the course guard both read it without a special case. + */ readonly courses = computed(() => this.user()?.courses ?? []); /** Loads the session once (cached). Returns the user, or null if not authenticated. */ @@ -34,18 +40,32 @@ export class AuthService { ); } - login(userName: string, password: string): Observable { + /** + * Signs in. Resolves to null on success, or to the reason it failed — the API's own message for a bad + * password or a locked-out account, and a distinct one when the backend cannot be reached at all. + */ + login(userName: string, password: string): Observable { const request: LoginRequest = { userName, password, rememberMe: true }; return this.authClient.login(request).pipe( tap((u) => this.setUser(u)), - map(() => true), - catchError(() => of(false)), + map(() => null), + catchError((err: unknown) => of(readApiError(err, 'That username and password do not match an account.'))), ); } + /** + * Clears the portal session. When the API returns an `endSessionUrl` the provider supports RP-initiated + * logout, so the browser is sent there to end the SSO session too; the BME IdP advertises no such endpoint + * today, so sign-out is local-only and this stays null. + */ logout(): Observable { return this.authClient.logout().pipe( - tap(() => this.setLoggedOut()), + tap((result) => { + this.setLoggedOut(); + if (result?.endSessionUrl) { + window.location.href = result.endSessionUrl; + } + }), map(() => undefined), catchError(() => { this.setLoggedOut(); @@ -55,7 +75,16 @@ export class AuthService { } isMemberOf(slug: string): boolean { - return this.isAdmin() || this.courses().some((c) => c.slug === slug); + return this.courses().some((c) => c.slug === slug); + } + + /** Where signing in should land: the admin console for admins, otherwise the first course they can open. */ + landingUrl(): string { + if (this.isAdmin()) { + return '/admin/courses'; + } + const first = this.courses()[0]; + return first ? `/${first.slug}/dashboard` : '/no-access'; } private setUser(u: CurrentUserResponse): void { diff --git a/ahk-frontend/src/app/core/course/course-context.service.ts b/ahk-frontend/src/app/core/course/course-context.service.ts index 95d5abc9..fc8652bd 100644 --- a/ahk-frontend/src/app/core/course/course-context.service.ts +++ b/ahk-frontend/src/app/core/course/course-context.service.ts @@ -3,8 +3,8 @@ import { Injectable, computed, inject, signal } from '@angular/core'; import { AuthService } from '../auth/auth.service'; /** - * Tracks the course the current route is scoped to (the {course} path segment). The active course record is - * derived from the user's memberships loaded in {@link AuthService}. + * Tracks the course the current route is scoped to (the {course} path segment), or null on the site-admin + * screens. The active course record is derived from the courses {@link AuthService} says the user can open. */ @Injectable({ providedIn: 'root' }) export class CourseContextService { diff --git a/ahk-frontend/src/app/core/course/course.guard.ts b/ahk-frontend/src/app/core/course/course.guard.ts index f312acc8..9364da72 100644 --- a/ahk-frontend/src/app/core/course/course.guard.ts +++ b/ahk-frontend/src/app/core/course/course.guard.ts @@ -6,9 +6,10 @@ import { AuthService } from '../auth/auth.service'; import { CourseContextService } from './course-context.service'; /** - * Guards /{course}/... routes: the user must be a member of the course (or a site admin). On success the - * course context is set so the shell can display it. Backend authorization is the real gate; this avoids - * navigating into a course the user cannot access. + * Guards /{course}/... routes: the course must be one the user can open. Site admins can open every course, + * which the API already reflects in the list this reads, so no special case is needed here. On success the + * course context is set so the shell can display it. Backend authorization is the real gate; this just avoids + * navigating into a course that would only return 403. */ export const courseGuard: CanActivateFn = (route) => { const auth = inject(AuthService); @@ -25,7 +26,7 @@ export const courseGuard: CanActivateFn = (route) => { courseContext.setActiveSlug(slug); return true; } - return router.createUrlTree(['/login']); + return router.createUrlTree([auth.landingUrl()]); }), ); }; diff --git a/ahk-frontend/src/app/features/admin/courses/course-editor.html b/ahk-frontend/src/app/features/admin/courses/course-editor.html new file mode 100644 index 00000000..4c9052e8 --- /dev/null +++ b/ahk-frontend/src/app/features/admin/courses/course-editor.html @@ -0,0 +1,408 @@ +@if (loading()) { +

Loading course…

+} @else if (course(); as c) { +
+} @else { +

That course does not exist. Back to courses

+} diff --git a/ahk-frontend/src/app/features/admin/courses/course-editor.scss b/ahk-frontend/src/app/features/admin/courses/course-editor.scss new file mode 100644 index 00000000..1d6bd616 --- /dev/null +++ b/ahk-frontend/src/app/features/admin/courses/course-editor.scss @@ -0,0 +1,110 @@ +textarea { + font-size: 0.75rem; + resize: vertical; +} + +.warn-text { + color: var(--warn); +} + +/* A "Remove it" affordance that lives inside a hint sentence, so it reads as prose, not a control. */ +.linkish { + border: 0; + background: none; + padding: 0; + font: inherit; + color: var(--accent); + cursor: pointer; + text-decoration: underline; +} + +.grow-input { + flex: 1 1 16rem; +} + +.card-foot.stack { + flex-direction: column; + align-items: stretch; +} + +.add-member { + display: flex; + align-items: center; + gap: 0.75rem; + width: 100%; +} + +.issued { + border-bottom: 1px solid var(--rule); +} + +.kv { + display: grid; + grid-template-columns: auto 1fr; + gap: 0.25rem 1rem; + margin: 0 0 1rem; + font-size: 0.8125rem; + + dt { + font-family: var(--font-ui); + font-size: 0.625rem; + letter-spacing: 0.1em; + text-transform: uppercase; + color: var(--ink-2); + } + + dd { + margin: 0; + word-break: break-all; + } +} + +.candidates { + list-style: none; + margin: 0.75rem 0 0; + padding: 0; + border: 1px solid var(--rule); + border-radius: var(--radius); + width: 100%; + + li { + display: flex; + align-items: center; + gap: 0.75rem; + flex-wrap: wrap; + padding: 0.5rem 0.75rem; + border-bottom: 1px solid var(--rule); + background: var(--surface); + font-size: 0.8125rem; + + &:last-child { + border-bottom: 0; + } + } + + .spacer { + flex: 1 1 auto; + } +} + +.danger-zone { + border-color: color-mix(in srgb, var(--bad) 30%, var(--rule)); + + > header { + border-bottom-color: color-mix(in srgb, var(--bad) 30%, var(--rule)); + } + + h2 { + color: var(--bad); + } + + .card-foot { + background: var(--bad-wash); + border-top-color: color-mix(in srgb, var(--bad) 30%, var(--rule)); + } +} + +select { + width: auto; + min-width: 10rem; +} diff --git a/ahk-frontend/src/app/features/admin/courses/course-editor.ts b/ahk-frontend/src/app/features/admin/courses/course-editor.ts new file mode 100644 index 00000000..e56f949d --- /dev/null +++ b/ahk-frontend/src/app/features/admin/courses/course-editor.ts @@ -0,0 +1,323 @@ +import { DatePipe } from '@angular/common'; +import { Component, OnInit, computed, inject, signal } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { ActivatedRoute, Router, RouterLink } from '@angular/router'; + +import { + CourseDetailDto, + CourseHealthAdminClient, + CourseHealthReport, + CourseMemberDto, + CourseRole, + CoursesAdminClient, + UpdateCourseGitHubConfigRequest, + UpdateCourseRequest, + UserDto, + UsersAdminClient, + WebhookTokenDto, +} from '../../../api/api-client'; +import { HealthChain } from '../../../shared/health-chain/health-chain'; + +/** + * Everything one course holds, on one page: what it is, how it talks to GitHub, which tokens accept its + * evaluation results, and who staffs it. + * + * Stored credentials are never sent to the browser, so their inputs start empty and mean "leave as is". Only a + * field the admin actually typed into is submitted — that is what lets an unchanged form be saved safely. + */ +@Component({ + selector: 'app-course-editor', + imports: [FormsModule, RouterLink, DatePipe, HealthChain], + templateUrl: './course-editor.html', + styleUrl: './course-editor.scss', +}) +export class CourseEditor implements OnInit { + private readonly client = inject(CoursesAdminClient); + private readonly usersClient = inject(UsersAdminClient); + private readonly healthClient = inject(CourseHealthAdminClient); + private readonly route = inject(ActivatedRoute); + private readonly router = inject(Router); + + protected readonly course = signal(null); + protected readonly report = signal(null); + protected readonly loading = signal(true); + protected readonly checking = signal(false); + protected readonly error = signal(null); + protected readonly saved = signal(null); + + private courseId = 0; + + // ---- Settings form ---- + protected slug = ''; + protected name = ''; + protected organization = ''; + protected repoPrefix = ''; + protected readonly savingSettings = signal(false); + + /** Renaming the slug moves every URL the course is reachable at, so the form says so before it is saved. */ + protected readonly slugChanged = computed(() => this.course() !== null && this.slug !== this.course()?.slug); + + // ---- GitHub integration form ---- + protected appId = ''; + protected appPrivateKey = ''; + protected accessToken = ''; + protected webhookSecret = ''; + protected workflowRunThreshold = 5; + protected integrationEnabled = true; + protected readonly savingIntegration = signal(false); + protected readonly clearing = signal>({}); + + // ---- Tokens ---- + protected newTokenDescription = ''; + protected readonly issuedToken = signal(null); + protected readonly creatingToken = signal(false); + + // ---- Staff ---- + protected memberSearch = ''; + protected readonly candidates = signal([]); + protected readonly searching = signal(false); + + // ---- Delete ---- + protected confirmSlug = ''; + protected readonly deleting = signal(false); + + ngOnInit(): void { + this.courseId = Number(this.route.snapshot.paramMap.get('id')); + this.load(); + this.runHealthCheck(); + } + + private load(): void { + this.loading.set(true); + this.client.get(this.courseId).subscribe({ + next: (course) => { + this.course.set(course); + this.slug = course.slug ?? ''; + this.name = course.name ?? ''; + this.organization = course.gitHubOrganization ?? ''; + this.repoPrefix = course.repoNamePrefix ?? ''; + this.appId = course.gitHubConfig?.gitHubAppId ?? ''; + this.workflowRunThreshold = course.gitHubConfig?.workflowRunThreshold ?? 5; + this.integrationEnabled = course.gitHubConfig?.enabled ?? true; + this.loading.set(false); + }, + error: () => { + this.error.set('That course could not be loaded.'); + this.loading.set(false); + }, + }); + } + + protected runHealthCheck(): void { + this.checking.set(true); + this.healthClient.checkCourse(this.courseId).subscribe({ + next: (report) => { + this.report.set(report); + this.checking.set(false); + }, + error: () => this.checking.set(false), + }); + } + + // ---- Settings ---- + + protected saveSettings(): void { + this.clearMessages(); + this.savingSettings.set(true); + + const request: UpdateCourseRequest = { + slug: this.slug.trim(), + name: this.name.trim(), + gitHubOrganization: this.organization.trim() || undefined, + repoNamePrefix: this.repoPrefix.trim() || undefined, + }; + + this.client.update(this.courseId, request).subscribe({ + next: () => { + this.savingSettings.set(false); + this.saved.set('Course settings saved.'); + this.load(); + this.runHealthCheck(); + }, + error: (err: unknown) => { + this.savingSettings.set(false); + this.error.set( + (err as { status?: number }).status === 409 + ? `The slug "${request.slug}" belongs to another course. Pick a different one.` + : 'The settings could not be saved.', + ); + }, + }); + } + + // ---- GitHub integration ---- + + /** Marks a stored credential for removal; the input is then disabled until the change is saved or undone. */ + protected toggleClear(field: string): void { + const next = { ...this.clearing() }; + next[field] = !next[field]; + this.clearing.set(next); + } + + protected isClearing(field: string): boolean { + return this.clearing()[field] === true; + } + + protected saveIntegration(): void { + this.clearMessages(); + this.savingIntegration.set(true); + + const request: UpdateCourseGitHubConfigRequest = { + gitHubAppId: this.appId.trim() || undefined, + gitHubAppPrivateKey: this.secretValue('appPrivateKey', this.appPrivateKey), + gitHubAccessToken: this.secretValue('accessToken', this.accessToken), + gitHubWebhookSecret: this.secretValue('webhookSecret', this.webhookSecret), + workflowRunThreshold: this.workflowRunThreshold, + enabled: this.integrationEnabled, + }; + + this.client.updateGitHubConfig(this.courseId, request).subscribe({ + next: () => { + this.savingIntegration.set(false); + this.appPrivateKey = ''; + this.accessToken = ''; + this.webhookSecret = ''; + this.clearing.set({}); + this.saved.set('GitHub integration saved.'); + this.load(); + this.runHealthCheck(); + }, + error: () => { + this.savingIntegration.set(false); + this.error.set('The GitHub integration could not be saved.'); + }, + }); + } + + /** + * Translates a credential input into what the API expects: undefined keeps the stored value, an empty string + * clears it, anything else replaces it. + */ + private secretValue(field: string, typed: string): string | undefined { + if (this.isClearing(field)) { + return ''; + } + return typed.trim() || undefined; + } + + // ---- CI callback tokens ---- + + protected createToken(): void { + this.clearMessages(); + this.creatingToken.set(true); + + this.client.createToken(this.courseId, { description: this.newTokenDescription.trim() || undefined }).subscribe({ + next: (token) => { + this.creatingToken.set(false); + this.newTokenDescription = ''; + this.issuedToken.set(token); + this.load(); + this.runHealthCheck(); + }, + error: () => { + this.creatingToken.set(false); + this.error.set('The token could not be created.'); + }, + }); + } + + protected revokeToken(token: WebhookTokenDto): void { + this.clearMessages(); + this.client.revokeToken(this.courseId, token.id ?? 0).subscribe({ + next: () => { + this.saved.set(`Token ${token.token} revoked. Evaluations signed with it will be rejected.`); + this.load(); + this.runHealthCheck(); + }, + error: () => this.error.set('The token could not be revoked.'), + }); + } + + protected dismissIssuedToken(): void { + this.issuedToken.set(null); + } + + // ---- Staff ---- + + protected searchUsers(): void { + const term = this.memberSearch.trim(); + if (term.length < 2) { + this.candidates.set([]); + return; + } + + this.searching.set(true); + this.usersClient.list(term, undefined, 0, 10).subscribe({ + next: (page) => { + this.candidates.set(page.items ?? []); + this.searching.set(false); + }, + error: () => this.searching.set(false), + }); + } + + protected addMember(user: UserDto, role: CourseRole): void { + this.clearMessages(); + this.client.upsertMember(this.courseId, { userId: user.id ?? 0, role }).subscribe({ + next: () => { + this.memberSearch = ''; + this.candidates.set([]); + this.saved.set(`${user.userName} was added to this course.`); + this.load(); + }, + error: () => this.error.set('That user could not be added.'), + }); + } + + protected changeMemberRole(member: CourseMemberDto, role: string): void { + this.clearMessages(); + this.client.upsertMember(this.courseId, { userId: member.userId ?? 0, role: role as CourseRole }).subscribe({ + next: () => this.load(), + error: () => this.error.set('That role could not be changed.'), + }); + } + + protected removeMember(member: CourseMemberDto): void { + this.clearMessages(); + this.client.removeMember(this.courseId, member.userId ?? 0).subscribe({ + next: () => { + this.saved.set(`${member.userName} was removed from this course.`); + this.load(); + }, + error: () => this.error.set('That member could not be removed.'), + }); + } + + /** Members already on the course are filtered out of the picker, so adding twice is not offered. */ + protected isMember(user: UserDto): boolean { + return (this.course()?.members ?? []).some((m) => m.userId === user.id); + } + + // ---- Delete ---- + + protected deleteCourse(): void { + this.clearMessages(); + this.deleting.set(true); + + this.client.delete(this.courseId, this.confirmSlug.trim()).subscribe({ + next: () => { + this.deleting.set(false); + void this.router.navigate(['/admin/courses']); + }, + error: () => { + this.deleting.set(false); + this.error.set('The course was not deleted. The slug must match exactly.'); + }, + }); + } + + private clearMessages(): void { + this.error.set(null); + this.saved.set(null); + } +} diff --git a/ahk-frontend/src/app/features/admin/courses/courses.html b/ahk-frontend/src/app/features/admin/courses/courses.html index 2acdce03..445059b0 100644 --- a/ahk-frontend/src/app/features/admin/courses/courses.html +++ b/ahk-frontend/src/app/features/admin/courses/courses.html @@ -1,32 +1,149 @@ -
-

Courses

+
+
+
+ Site administration +

Courses

+

+ Every course runs its own GitHub organization, credentials and callback token. This is the register of + them, and the state of each one's integration. +

+
+
+ + +
+
@if (error(); as e) { -

{{ e }}

+

{{ e }}

} - - - - - - @for (c of courses(); track c.id) { - - - - - - - } @empty { - - } - -
SlugNameGitHub orgCreated
{{ c.slug }}{{ c.name }}{{ c.gitHubOrganization || '—' }}{{ c.createdAt | date: 'short' }}
No courses yet.
+ @if (!loading() && failingCount() > 0) { +

+ {{ failingCount() }} {{ failingCount() === 1 ? 'course is' : 'courses are' }} failing a health check. + Open the course to see which link is broken. +

+ } + + @if (adding()) { +
+
+
+

Add course

+

The slug becomes the course's URL and cannot contain spaces or capitals.

+
+
+
+
+
+
+ + + Lowercase letters, digits and hyphens. Used as /viaubc01/… +
+
+ + +
+
+ + + Optional now; you can set it with the rest of the integration. +
+
+
+
+ + +
+
+
+ } -

Add course

-
- - - -
+
+ @if (loading()) { +

Loading courses…

+ } @else { +
+ + + + + + + + + + + + + + + @for (c of courses(); track c.id) { + + + + + + + + + + + } @empty { + + + + } + +
CourseGitHubStudentsSubmissionsStaffIntegrationCreated
+ {{ c.slug }} +
{{ c.name }}
+
+ {{ c.gitHubOrganization || '—' }} + @if (c.repoNamePrefix) { +
prefix {{ c.repoNamePrefix }}
+ } +
{{ c.studentCount }}{{ c.submissionCount }}{{ c.memberCount }} + @if (reportFor(c); as report) { + {{ verdict(report.status) }} + @if (problems(report); as p) { +
{{ p }}
+ } + } @else { + Not checked + } +
{{ c.createdAt | date: 'yyyy-MM-dd' }} + Open + Edit +
+ No courses yet. Add one to start receiving submissions. +
+
+ } +
diff --git a/ahk-frontend/src/app/features/admin/courses/courses.scss b/ahk-frontend/src/app/features/admin/courses/courses.scss index 7771f5b4..2888c7fb 100644 --- a/ahk-frontend/src/app/features/admin/courses/courses.scss +++ b/ahk-frontend/src/app/features/admin/courses/courses.scss @@ -1,46 +1,13 @@ -.admin-courses { - max-width: 48rem; - - h1 { - font-size: 1.4rem; - } - - table { - width: 100%; - border-collapse: collapse; - margin-bottom: 1.5rem; - - th, - td { - text-align: left; - padding: 0.4rem 0.6rem; - border-bottom: 1px solid #e2e8f0; - font-size: 0.9rem; - } - } - - .new-course { - display: flex; - gap: 0.5rem; - flex-wrap: wrap; - - input { - padding: 0.45rem; - border: 1px solid #cbd5e1; - border-radius: 4px; - } +.strong { + font-weight: 600; +} - button { - padding: 0.45rem 0.9rem; - border: 0; - border-radius: 4px; - background: #2563eb; - color: #fff; - cursor: pointer; - } - } +td .muted { + font-size: 0.75rem; +} - .error { - color: #dc2626; - } +/* The verdict plus the names of the failing checks; the full chain lives on the health page. */ +.health-cell { + min-width: 12rem; + max-width: 20rem; } diff --git a/ahk-frontend/src/app/features/admin/courses/courses.ts b/ahk-frontend/src/app/features/admin/courses/courses.ts index 6ccb0452..73c049a6 100644 --- a/ahk-frontend/src/app/features/admin/courses/courses.ts +++ b/ahk-frontend/src/app/features/admin/courses/courses.ts @@ -1,46 +1,163 @@ import { DatePipe } from '@angular/common'; -import { Component, OnInit, inject, signal } from '@angular/core'; +import { Component, OnInit, computed, inject, signal } from '@angular/core'; import { FormsModule } from '@angular/forms'; +import { Router, RouterLink } from '@angular/router'; +import { forkJoin } from 'rxjs'; -import { CoursesAdminClient, CourseDto, CreateCourseRequest } from '../../../api/api-client'; +import { + CourseDto, + CourseHealthAdminClient, + CourseHealthReport, + CoursesAdminClient, + CreateCourseRequest, + HealthStatus, +} from '../../../api/api-client'; -/** Host/admin screen: list and create courses (their connected GitHub environments come in the port). */ +/** + * The site's course register. Each row carries the course's identity, its size, and a one-line verdict on its + * integration, so an admin can tell a working course from a half-configured one without opening it. The full + * chain of checks is one click away, on the health page and in the course editor. + */ @Component({ selector: 'app-admin-courses', - imports: [FormsModule, DatePipe], + imports: [FormsModule, RouterLink, DatePipe], templateUrl: './courses.html', styleUrl: './courses.scss', }) export class AdminCourses implements OnInit { private readonly client = inject(CoursesAdminClient); + private readonly healthClient = inject(CourseHealthAdminClient); + private readonly router = inject(Router); protected readonly courses = signal([]); + protected readonly health = signal>(new Map()); + protected readonly loading = signal(false); + protected readonly checking = signal(false); protected readonly error = signal(null); + protected readonly adding = signal(false); + protected readonly saving = signal(false); protected slug = ''; protected name = ''; + protected organization = ''; + + /** Courses whose integration is failing — the number the page leads with. */ + protected readonly failingCount = computed( + () => [...this.health().values()].filter((r) => r.status === 'Failed').length, + ); ngOnInit(): void { this.reload(); } protected reload(): void { - this.client.list().subscribe({ - next: (list) => this.courses.set(list), - error: () => this.error.set('Failed to load courses.'), + this.loading.set(true); + this.error.set(null); + + // The health run is the slow half (it calls GitHub), but the two arrive together so the table never + // reflows under the reader. + forkJoin({ courses: this.client.list(), reports: this.healthClient.checkAll() }).subscribe({ + next: ({ courses, reports }) => { + this.courses.set(courses); + this.health.set(new Map(reports.map((r) => [r.courseId ?? 0, r]))); + this.loading.set(false); + }, + error: () => { + this.error.set('Could not load the courses. Reload the page to try again.'); + this.loading.set(false); + }, }); } + protected recheck(): void { + this.checking.set(true); + this.healthClient.checkAll().subscribe({ + next: (reports) => { + this.health.set(new Map(reports.map((r) => [r.courseId ?? 0, r]))); + this.checking.set(false); + }, + error: () => { + this.error.set('The health check could not be run.'); + this.checking.set(false); + }, + }); + } + + protected reportFor(course: CourseDto): CourseHealthReport | undefined { + return this.health().get(course.id ?? 0); + } + + protected tone(status: HealthStatus | undefined): string { + switch (status) { + case 'Healthy': + return 'ok'; + case 'Warning': + return 'warn'; + case 'Failed': + return 'bad'; + default: + return ''; + } + } + + protected verdict(status: HealthStatus | undefined): string { + switch (status) { + case 'Healthy': + return 'Passing'; + case 'Warning': + return 'Needs attention'; + case 'Failed': + return 'Failing'; + default: + return 'Not set up'; + } + } + + /** Names the checks that are not passing, so the row says what to go and fix. */ + protected problems(report: CourseHealthReport): string { + return (report.checks ?? []) + .filter((c) => c.status !== 'Healthy') + .map((c) => c.title) + .join(', '); + } + + protected startAdding(): void { + this.adding.set(true); + this.error.set(null); + } + + protected cancelAdding(): void { + this.adding.set(false); + this.slug = ''; + this.name = ''; + this.organization = ''; + } + + /** Creates the course and opens its editor — the next thing to do is always fill in the integration. */ protected create(): void { this.error.set(null); - const request: CreateCourseRequest = { slug: this.slug, name: this.name }; + this.saving.set(true); + + const request: CreateCourseRequest = { + slug: this.slug.trim(), + name: this.name.trim(), + gitHubOrganization: this.organization.trim() || undefined, + }; + this.client.create(request).subscribe({ - next: () => { - this.slug = ''; - this.name = ''; - this.reload(); + next: (course) => { + this.saving.set(false); + this.cancelAdding(); + void this.router.navigate(['/admin/courses', course.id]); + }, + error: (err: unknown) => { + this.saving.set(false); + this.error.set( + (err as { status?: number }).status === 409 + ? `The slug "${request.slug}" is already taken. Pick another one.` + : 'The course could not be created. Check the slug and name, then try again.', + ); }, - error: () => this.error.set('Failed to create course (slug may already exist).'), }); } } diff --git a/ahk-frontend/src/app/features/admin/health/health.html b/ahk-frontend/src/app/features/admin/health/health.html new file mode 100644 index 00000000..a86ee328 --- /dev/null +++ b/ahk-frontend/src/app/features/admin/health/health.html @@ -0,0 +1,77 @@ +
+
+
+ Site administration +

Health

+

+ Every course's integration, checked now. The GitHub access token is verified against GitHub itself; the + rest is read from what is stored. +

+
+
+ +
+
+ + @if (error(); as e) { +

{{ e }}

+ } + + @if (!loading() && reports().length > 0) { +
+
+ {{ counts().failed }} + Failing +
+
+ {{ counts().warning }} + Need attention +
+
+ {{ counts().notConfigured }} + Not set up +
+
+ {{ counts().healthy }} + Passing +
+ @if (checkedAt(); as at) { + Checked {{ at | date: 'medium' }} + } +
+ } + + @if (loading() && reports().length === 0) { +

Running checks against every course…

+ } + + @for (r of sorted(); track r.courseId) { +
+
+ +
+

+ {{ r.courseSlug }} + {{ r.courseName }} +

+

{{ summaryFor(r) }}

+
+ Fix in settings +
+
+ +
+
+ } @empty { + @if (!loading()) { +

There are no courses to check yet.

+ } + } +
diff --git a/ahk-frontend/src/app/features/admin/health/health.scss b/ahk-frontend/src/app/features/admin/health/health.scss new file mode 100644 index 00000000..6c46c2f1 --- /dev/null +++ b/ahk-frontend/src/app/features/admin/health/health.scss @@ -0,0 +1,67 @@ +.tally { + display: flex; + align-items: center; + gap: 0.75rem; + flex-wrap: wrap; + margin-bottom: 1.25rem; +} + +.tile { + display: flex; + flex-direction: column; + gap: 0.125rem; + min-width: 7rem; + padding: 0.625rem 0.875rem; + background: var(--surface); + border: 1px solid var(--rule); + border-left: 3px solid var(--rule-strong); + border-radius: var(--radius); + + &.ok { + border-left-color: var(--ok); + } + + &.warn { + border-left-color: var(--warn); + } + + &.bad { + border-left-color: var(--bad); + } + + .n { + font-family: var(--font-mono); + font-size: 1.375rem; + font-weight: 600; + line-height: 1.1; + font-variant-numeric: tabular-nums; + } + + .l { + font-family: var(--font-ui); + font-size: 0.625rem; + letter-spacing: 0.1em; + text-transform: uppercase; + color: var(--ink-2); + } +} + +.stamp { + font-size: 0.75rem; + color: var(--ink-2); + margin-left: auto; +} + +h2 { + display: flex; + align-items: baseline; + gap: 0.625rem; + flex-wrap: wrap; +} + +.course-name { + font-family: var(--font-ui); + font-size: 0.8125rem; + font-weight: 400; + color: var(--ink-2); +} diff --git a/ahk-frontend/src/app/features/admin/health/health.ts b/ahk-frontend/src/app/features/admin/health/health.ts new file mode 100644 index 00000000..9917113f --- /dev/null +++ b/ahk-frontend/src/app/features/admin/health/health.ts @@ -0,0 +1,100 @@ +import { DatePipe } from '@angular/common'; +import { Component, OnInit, computed, inject, signal } from '@angular/core'; +import { RouterLink } from '@angular/router'; + +import { CourseHealthAdminClient, CourseHealthReport, HealthStatus } from '../../../api/api-client'; +import { HealthChain } from '../../../shared/health-chain/health-chain'; + +/** + * Health of every course in one place: which integrations work, which are half-configured, and what to do + * about the ones that are not. Failing courses sort to the top, because that is the only reason to open this + * page twice. + */ +@Component({ + selector: 'app-admin-health', + imports: [RouterLink, DatePipe, HealthChain], + templateUrl: './health.html', + styleUrl: './health.scss', +}) +export class AdminHealth implements OnInit { + private readonly client = inject(CourseHealthAdminClient); + + protected readonly reports = signal([]); + protected readonly loading = signal(false); + protected readonly error = signal(null); + protected readonly checkedAt = signal(null); + + /** Worst first, then alphabetical — the reading order matches the order to act in. */ + private static readonly severity: Record = { + Failed: 0, + Warning: 1, + NotConfigured: 2, + Healthy: 3, + }; + + protected readonly sorted = computed(() => + [...this.reports()].sort((a, b) => { + const bySeverity = + AdminHealth.severity[a.status ?? 'NotConfigured'] - AdminHealth.severity[b.status ?? 'NotConfigured']; + return bySeverity !== 0 ? bySeverity : (a.courseSlug ?? '').localeCompare(b.courseSlug ?? ''); + }), + ); + + protected readonly counts = computed(() => { + const all = this.reports(); + return { + total: all.length, + failed: all.filter((r) => r.status === 'Failed').length, + warning: all.filter((r) => r.status === 'Warning').length, + notConfigured: all.filter((r) => r.status === 'NotConfigured').length, + healthy: all.filter((r) => r.status === 'Healthy').length, + }; + }); + + ngOnInit(): void { + this.run(); + } + + protected run(): void { + this.loading.set(true); + this.error.set(null); + + this.client.checkAll().subscribe({ + next: (reports) => { + this.reports.set(reports); + this.checkedAt.set(new Date()); + this.loading.set(false); + }, + error: () => { + this.error.set('The checks could not be run. Reload the page to try again.'); + this.loading.set(false); + }, + }); + } + + protected tone(status: HealthStatus | undefined): string { + switch (status) { + case 'Healthy': + return 'ok'; + case 'Warning': + return 'warn'; + case 'Failed': + return 'bad'; + default: + return ''; + } + } + + protected summaryFor(report: CourseHealthReport): string { + switch (report.status) { + case 'Healthy': + return 'Everything checks out.'; + case 'Failed': + return 'Part of this integration is broken.'; + case 'Warning': + return 'Works, but something needs attention.'; + default: + return 'Not set up yet.'; + } + } +} diff --git a/ahk-frontend/src/app/features/admin/users/users.html b/ahk-frontend/src/app/features/admin/users/users.html new file mode 100644 index 00000000..a2c4792e --- /dev/null +++ b/ahk-frontend/src/app/features/admin/users/users.html @@ -0,0 +1,257 @@ +
+
+
+ Site administration +

Users

+

+ Accounts that can sign in. BME accounts appear here after their first sign-on; local accounts are + created below. +

+
+
+ +
+
+ + @if (error(); as e) { +

{{ e }}

+ } + @if (saved(); as s) { +

{{ s }}

+ } + + @if (adding()) { +
+
+
+

Add local account

+

For people without a BME account, or for service logins.

+
+
+
+
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + + At least 6 characters. Tell the person to change it after signing in. +
+
+
+
+ + +
+
+
+ } + +
+
+ + + + + @if (total() > 0) { + {{ showingRange().from }}–{{ showingRange().to }} of {{ total() }} + } + +
+ + @if (loading()) { +

Loading users…

+ } @else { +
+ + + + + + + + + + + + @for (u of users(); track u.id) { + + + + + + + + + @if (expanded() === u.id) { + + + + } + } @empty { + + + + } + +
UserSign-inSite roleCourses
+ {{ u.userName }} + @if (u.displayName) { +
{{ u.displayName }}
+ } + @if (u.email) { +
{{ u.email }}
+ } +
+ @if (u.isExternal) { + BME account + } @else { + Password + } + @if (u.isLockedOut) { +
Locked out
+ } + @if (u.neptunCode) { +
{{ u.neptunCode }}
+ } +
+ + + @if (u.courses?.length) { +
+ @for (c of u.courses; track c.courseId) { + + {{ c.slug }} + @if (c.role === 'Admin') { + · admin + } + + } +
+ } @else { + None + } +
+ +
+
+
+

Course assignments

+ @if (u.courses?.length) { +
    + @for (c of u.courses; track c.courseId) { +
  • + {{ c.slug }} + {{ c.name }} + + + +
  • + } +
+ } @else { +

Not assigned to any course.

+ } + + @if (assignableCourses(u).length > 0) { +
+ + + +
+ } +
+ + +
+
No account matches this search.
+
+ + @if (total() > users().length) { +
+ + +
+ } + } +
+
diff --git a/ahk-frontend/src/app/features/admin/users/users.scss b/ahk-frontend/src/app/features/admin/users/users.scss new file mode 100644 index 00000000..7fe241e9 --- /dev/null +++ b/ahk-frontend/src/app/features/admin/users/users.scss @@ -0,0 +1,85 @@ +.search { + flex: 1 1 18rem; + max-width: 26rem; +} + +.filter, +select { + width: auto; + min-width: 9rem; +} + +td .muted { + font-size: 0.75rem; +} + +.course-tags { + display: flex; + flex-wrap: wrap; + gap: 0.25rem; + max-width: 22rem; +} + +/* Managing one user opens a drawer under their row, so the list keeps its place. */ +tr.drawer td { + background: var(--surface-2); + padding: 0; +} + +.drawer-inner { + display: grid; + grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); + gap: 1.5rem; + padding: 1.125rem; + border-top: 1px solid var(--rule); +} + +@media (max-width: 60rem) { + .drawer-inner { + grid-template-columns: 1fr; + } +} + +h3 { + margin-bottom: 0.625rem; + color: var(--ink-2); + letter-spacing: 0.06em; + text-transform: uppercase; + font-size: 0.6875rem; +} + +.assigned { + list-style: none; + margin: 0 0 0.875rem; + padding: 0; + + li { + display: flex; + align-items: center; + gap: 0.625rem; + flex-wrap: wrap; + padding: 0.375rem 0; + border-bottom: 1px solid var(--rule); + font-size: 0.8125rem; + } + + .spacer { + flex: 1 1 auto; + } +} + +.add-course { + display: flex; + align-items: center; + gap: 0.5rem; + flex-wrap: wrap; +} + +.account .btn { + margin-bottom: 0.5rem; +} + +.small { + font-size: 0.75rem; + margin: 0; +} diff --git a/ahk-frontend/src/app/features/admin/users/users.ts b/ahk-frontend/src/app/features/admin/users/users.ts new file mode 100644 index 00000000..53fe80e7 --- /dev/null +++ b/ahk-frontend/src/app/features/admin/users/users.ts @@ -0,0 +1,249 @@ +import { Component, OnInit, computed, inject, signal } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { Subject, debounceTime, distinctUntilChanged, switchMap } from 'rxjs'; + +import { + CourseDto, + CourseRole, + CoursesAdminClient, + CreateUserRequest, + UserDto, + UsersAdminClient, +} from '../../../api/api-client'; +import { readApiError } from '../../../core/api-error'; + +const SITE_ADMIN = 'Admin'; + +/** + * The register of accounts: who exists, what they can do site-wide, and which courses they are assigned to. + * Roles and course assignments are edited in place — they are the two things an admin changes often, and a + * separate edit screen for each would double the clicks. + */ +@Component({ + selector: 'app-admin-users', + imports: [FormsModule], + templateUrl: './users.html', + styleUrl: './users.scss', +}) +export class AdminUsers implements OnInit { + private readonly client = inject(UsersAdminClient); + private readonly coursesClient = inject(CoursesAdminClient); + + protected readonly users = signal([]); + protected readonly total = signal(0); + protected readonly courses = signal([]); + protected readonly loading = signal(false); + protected readonly error = signal(null); + protected readonly saved = signal(null); + + protected search = ''; + protected courseFilter = ''; + private readonly pageSize = 50; + protected readonly skip = signal(0); + + private readonly searchTerm = new Subject(); + + /** The user row currently expanded for course assignment. */ + protected readonly expanded = signal(null); + + protected readonly adding = signal(false); + protected readonly savingNew = signal(false); + protected newUserName = ''; + protected newEmail = ''; + protected newDisplayName = ''; + protected newPassword = ''; + + protected readonly showingRange = computed(() => { + const from = this.users().length === 0 ? 0 : this.skip() + 1; + return { from, to: this.skip() + this.users().length }; + }); + + ngOnInit(): void { + this.coursesClient.list().subscribe({ + next: (list) => this.courses.set(list), + error: () => this.error.set('The course list could not be loaded, so course assignment is unavailable.'), + }); + + // Typing a search re-queries the server rather than filtering a page, so a name outside the first 50 rows + // is still findable. + this.searchTerm + .pipe( + debounceTime(250), + distinctUntilChanged(), + switchMap(() => { + this.loading.set(true); + return this.query(); + }), + ) + .subscribe({ + next: (page) => { + this.users.set(page.items ?? []); + this.total.set(page.total ?? 0); + this.loading.set(false); + }, + error: () => { + this.error.set('The users could not be loaded.'); + this.loading.set(false); + }, + }); + + this.reload(); + } + + private query() { + return this.client.list( + this.search.trim() || undefined, + this.courseFilter ? Number(this.courseFilter) : undefined, + this.skip(), + this.pageSize, + ); + } + + protected reload(): void { + this.loading.set(true); + this.query().subscribe({ + next: (page) => { + this.users.set(page.items ?? []); + this.total.set(page.total ?? 0); + this.loading.set(false); + }, + error: () => { + this.error.set('The users could not be loaded.'); + this.loading.set(false); + }, + }); + } + + protected onSearchChange(): void { + this.skip.set(0); + this.searchTerm.next(`${this.search}|${this.courseFilter}`); + } + + protected page(delta: number): void { + this.skip.set(Math.max(0, this.skip() + delta * this.pageSize)); + this.reload(); + } + + // ---- Site role ---- + + protected isSiteAdmin(user: UserDto): boolean { + return (user.roles ?? []).includes(SITE_ADMIN); + } + + protected toggleSiteAdmin(user: UserDto, makeAdmin: boolean): void { + this.clearMessages(); + const roles = makeAdmin ? [SITE_ADMIN] : []; + + this.client.updateRoles(user.id ?? 0, { roles }).subscribe({ + next: (updated) => { + this.replace(updated); + this.saved.set( + makeAdmin + ? `${updated.userName} is now a site admin.` + : `${updated.userName} is no longer a site admin.`, + ); + }, + error: (err: unknown) => { + // The API refuses to let an admin strip their own role; surface its reason rather than a generic one. + this.error.set(readApiError(err, 'That role could not be changed.')); + this.reload(); + }, + }); + } + + // ---- Course assignment ---- + + protected toggleExpanded(user: UserDto): void { + this.expanded.set(this.expanded() === user.id ? null : (user.id ?? null)); + } + + protected assignableCourses(user: UserDto): CourseDto[] { + const assigned = new Set((user.courses ?? []).map((c) => c.courseId)); + return this.courses().filter((c) => !assigned.has(c.id)); + } + + protected assign(user: UserDto, courseId: string, role: CourseRole): void { + if (!courseId) { + return; + } + this.clearMessages(); + this.client.upsertCourse(user.id ?? 0, { courseId: Number(courseId), role }).subscribe({ + next: (updated) => { + this.replace(updated); + this.saved.set(`${updated.userName}'s course assignments were updated.`); + }, + error: () => this.error.set('That course could not be assigned.'), + }); + } + + protected changeCourseRole(user: UserDto, courseId: number, role: string): void { + this.clearMessages(); + this.client.upsertCourse(user.id ?? 0, { courseId, role: role as CourseRole }).subscribe({ + next: (updated) => this.replace(updated), + error: () => this.error.set('That role could not be changed.'), + }); + } + + protected unassign(user: UserDto, courseId: number): void { + this.clearMessages(); + this.client.removeCourse(user.id ?? 0, courseId).subscribe({ + next: (updated) => this.replace(updated), + error: () => this.error.set('That course could not be removed.'), + }); + } + + // ---- Create ---- + + protected createUser(): void { + this.clearMessages(); + this.savingNew.set(true); + + const request: CreateUserRequest = { + userName: this.newUserName.trim(), + email: this.newEmail.trim() || undefined, + displayName: this.newDisplayName.trim() || undefined, + password: this.newPassword, + }; + + this.client.create(request).subscribe({ + next: (user) => { + this.savingNew.set(false); + this.cancelAdding(); + this.saved.set(`${user.userName} was created.`); + this.reload(); + }, + error: (err: unknown) => { + this.savingNew.set(false); + this.error.set(readApiError(err, 'That account could not be created.')); + }, + }); + } + + protected cancelAdding(): void { + this.adding.set(false); + this.newUserName = ''; + this.newEmail = ''; + this.newDisplayName = ''; + this.newPassword = ''; + } + + protected deleteUser(user: UserDto): void { + this.clearMessages(); + this.client.delete(user.id ?? 0).subscribe({ + next: () => { + this.saved.set(`${user.userName} was deleted.`); + this.reload(); + }, + error: (err: unknown) => this.error.set(readApiError(err, 'That account could not be deleted.')), + }); + } + + private replace(user: UserDto): void { + this.users.set(this.users().map((u) => (u.id === user.id ? user : u))); + } + + private clearMessages(): void { + this.error.set(null); + this.saved.set(null); + } +} diff --git a/ahk-frontend/src/app/features/course/dashboard/dashboard.html b/ahk-frontend/src/app/features/course/dashboard/dashboard.html index a7c45c72..b5e7513b 100644 --- a/ahk-frontend/src/app/features/course/dashboard/dashboard.html +++ b/ahk-frontend/src/app/features/course/dashboard/dashboard.html @@ -1,24 +1,157 @@ -
-

- @if (courseContext.activeCourse(); as course) { - {{ course.name }} - } @else { - Course - } -

+
+
+
+ {{ courseContext.activeSlug() }} +

{{ courseContext.activeCourse()?.name || 'Submissions' }}

+

Every student repository in this course, its state on GitHub, and its points.

+
+
+ + +
+
-

Course-scoped probe notes (skeleton demo of course isolation):

+ @if (error(); as e) { +

{{ e }}

+ } -
    - @for (n of notes(); track n.id) { -
  • {{ n.text }} {{ n.createdAt | date: 'short' }}
  • - } @empty { -
  • No notes for this course.
  • - } -
+ @if (!loading() && statuses().length > 0) { +
+
+ {{ summary().total }} + Submissions +
+
+ {{ summary().graded }} + Graded +
+
+ {{ summary().openPrs }} + With a pull request +
+
+ {{ summary().failing }} + Last run failed +
+
+ } -
- - -
+
+
+ + + + + @if (filtered()) { + {{ rows().length }} of {{ summary().total }} + + } +
+ + @if (loading()) { +

Loading submissions…

+ } @else { +
+ + + + + + + + + @for (ex of exerciseNames(); track ex) { + + } + @if (exerciseNames().length > 0) { + + } + + + + @for (s of rows(); track s.repository) { + + + + + + + @for (ex of exerciseNames(); track ex) { + + } + @if (exerciseNames().length > 0) { + + } + + } @empty { + + + + } + +
BranchesPull request{{ ex }}
{{ s.neptun || '—' }} + + {{ s.repository }} + + {{ s.branches?.join(', ') || '—' }} + @if (s.pullRequests?.length) { + @for (pr of s.pullRequests; track pr.number) { +
+ #{{ pr.number }} + {{ pr.status }} + @if (pr.assignee) { + {{ pr.assignee }} + } +
+ } + } @else { + + } +
+ {{ s.workflowRuns?.count ?? 0 }} + @if (s.workflowRuns?.lastStatus; as last) { + {{ last }} + } + + @if (pointsFor(s.repository, ex) !== null) { + {{ pointsFor(s.repository, ex) | number: '1.0-2' }} + } @else { + + } + + @if (totalFor(s.repository) !== null) { + {{ totalFor(s.repository) | number: '1.0-2' }} + } @else { + + } +
+ @if (filtered()) { + Nothing matches these filters. + + } @else { + No submissions in this course yet. They appear once students push to their repositories. + } +
+
+ } +
diff --git a/ahk-frontend/src/app/features/course/dashboard/dashboard.scss b/ahk-frontend/src/app/features/course/dashboard/dashboard.scss index 3b6a2570..23d737d8 100644 --- a/ahk-frontend/src/app/features/course/dashboard/dashboard.scss +++ b/ahk-frontend/src/app/features/course/dashboard/dashboard.scss @@ -1,54 +1,71 @@ -.dashboard { - max-width: 40rem; +.tally { + display: flex; + gap: 0.75rem; + flex-wrap: wrap; + margin-bottom: 1.25rem; +} + +.tile { + display: flex; + flex-direction: column; + gap: 0.125rem; + min-width: 8rem; + padding: 0.625rem 0.875rem; + background: var(--surface); + border: 1px solid var(--rule); + border-left: 3px solid var(--rule-strong); + border-radius: var(--radius); - h1 { - font-size: 1.4rem; + &.bad { + border-left-color: var(--bad); } - .hint { - color: #64748b; - font-size: 0.9rem; + .n { + font-family: var(--font-mono); + font-size: 1.375rem; + font-weight: 600; + line-height: 1.1; + font-variant-numeric: tabular-nums; } - ul { - list-style: none; - padding: 0; + .l { + font-family: var(--font-ui); + font-size: 0.625rem; + letter-spacing: 0.1em; + text-transform: uppercase; + color: var(--ink-2); + } +} - li { - padding: 0.4rem 0; - border-bottom: 1px solid #e2e8f0; +.search { + flex: 1 1 16rem; + max-width: 24rem; +} - small { - color: #94a3b8; - margin-left: 0.5rem; - } +/* Column headers double as sort controls; they keep the header's own type so the row still reads as a header. */ +.sort { + border: 0; + background: none; + padding: 0; + font: inherit; + color: inherit; + letter-spacing: inherit; + text-transform: inherit; + cursor: pointer; - &.empty { - color: #94a3b8; - border: 0; - } - } + &:hover { + color: var(--accent); } +} - .new-note { - display: flex; - gap: 0.5rem; - margin-top: 1rem; - - input { - flex: 1; - padding: 0.45rem; - border: 1px solid #cbd5e1; - border-radius: 4px; - } - - button { - padding: 0.45rem 0.9rem; - border: 0; - border-radius: 4px; - background: #2563eb; - color: #fff; - cursor: pointer; - } - } +.pr { + display: flex; + align-items: center; + gap: 0.375rem; + flex-wrap: wrap; +} + +td.total { + font-weight: 600; + border-left: 1px solid var(--rule); } diff --git a/ahk-frontend/src/app/features/course/dashboard/dashboard.ts b/ahk-frontend/src/app/features/course/dashboard/dashboard.ts index ed82ef1c..e95f31f0 100644 --- a/ahk-frontend/src/app/features/course/dashboard/dashboard.ts +++ b/ahk-frontend/src/app/features/course/dashboard/dashboard.ts @@ -1,26 +1,77 @@ -import { DatePipe } from '@angular/common'; -import { Component, OnInit, inject, signal } from '@angular/core'; +import { DecimalPipe } from '@angular/common'; +import { Component, OnInit, computed, inject, signal } from '@angular/core'; import { FormsModule } from '@angular/forms'; +import { forkJoin } from 'rxjs'; -import { CourseProbeClient, CourseNoteDto } from '../../../api/api-client'; +import { FinalStudentGrade, GradesClient, RepositoryStatus, SubmissionStatusesClient } from '../../../api/api-client'; import { CourseContextService } from '../../../core/course/course-context.service'; +type SortKey = 'neptun' | 'repository' | 'runs' | 'total'; + /** - * Course landing page. For this skeleton it reads/writes the course-scoped probe notes to demonstrate that - * course data is confined to the active course. Real course dashboards (submissions, grades) replace it. + * The instructor's view of a course: every submission, its state on GitHub, and its points. Site admins reach + * the same screen for any course, so nothing here assumes an explicit membership. + * + * Search, filtering and sorting all happen client-side — a course is a few hundred rows at most, and a + * round-trip per keystroke would be slower than the reader. */ @Component({ selector: 'app-course-dashboard', - imports: [FormsModule, DatePipe], + imports: [DecimalPipe, FormsModule], templateUrl: './dashboard.html', styleUrl: './dashboard.scss', }) export class CourseDashboard implements OnInit { - private readonly client = inject(CourseProbeClient); + private readonly statusesClient = inject(SubmissionStatusesClient); + private readonly gradesClient = inject(GradesClient); protected readonly courseContext = inject(CourseContextService); - protected readonly notes = signal([]); - protected text = ''; + protected readonly statuses = signal([]); + protected readonly grades = signal>(new Map()); + protected readonly exerciseNames = signal([]); + protected readonly loading = signal(false); + protected readonly error = signal(null); + + protected search = ''; + protected readonly searchTerm = signal(''); + protected readonly onlyUngraded = signal(false); + protected readonly onlyFailing = signal(false); + protected readonly sortKey = signal('neptun'); + protected readonly sortAsc = signal(true); + + protected readonly rows = computed(() => { + const term = this.searchTerm().trim().toLowerCase(); + const grades = this.grades(); + + let rows = this.statuses().filter((s) => { + if (term && !`${s.neptun ?? ''} ${s.repository ?? ''}`.toLowerCase().includes(term)) { + return false; + } + if (this.onlyUngraded() && grades.has(s.repository ?? '')) { + return false; + } + if (this.onlyFailing() && s.workflowRuns?.lastStatus !== 'failure') { + return false; + } + return true; + }); + + const key = this.sortKey(); + const direction = this.sortAsc() ? 1 : -1; + rows = [...rows].sort((a, b) => direction * this.compare(a, b, key)); + return rows; + }); + + protected readonly summary = computed(() => { + const all = this.statuses(); + const grades = this.grades(); + return { + total: all.length, + graded: all.filter((s) => grades.has(s.repository ?? '')).length, + openPrs: all.filter((s) => (s.pullRequests?.length ?? 0) > 0).length, + failing: all.filter((s) => s.workflowRuns?.lastStatus === 'failure').length, + }; + }); ngOnInit(): void { this.reload(); @@ -31,17 +82,87 @@ export class CourseDashboard implements OnInit { if (!slug) { return; } - this.client.getNotes(slug).subscribe((list) => this.notes.set(list)); + + this.loading.set(true); + this.error.set(null); + + forkJoin({ statuses: this.statusesClient.list(slug), grades: this.gradesClient.list(slug) }).subscribe({ + next: ({ statuses, grades }) => { + this.statuses.set(statuses); + this.grades.set(new Map(grades.map((g) => [g.repo ?? '', g]))); + + // Union of exercise names across students drives the table columns, like the CSV export. + const names = new Set(); + for (const g of grades) { + Object.keys(g.points ?? {}).forEach((n) => names.add(n)); + } + this.exerciseNames.set([...names].sort()); + this.loading.set(false); + }, + error: () => { + this.error.set('This course’s submissions could not be loaded.'); + this.loading.set(false); + }, + }); + } + + protected onSearchChange(): void { + this.searchTerm.set(this.search); + } + + protected sortBy(key: SortKey): void { + if (this.sortKey() === key) { + this.sortAsc.set(!this.sortAsc()); + } else { + this.sortKey.set(key); + this.sortAsc.set(true); + } } - protected add(): void { + protected pointsFor(repo: string | undefined, exercise: string): number | null { + return this.grades().get(repo ?? '')?.points?.[exercise] ?? null; + } + + protected totalFor(repo: string | undefined): number | null { + const points = this.grades().get(repo ?? '')?.points; + if (!points) { + return null; + } + return Object.values(points).reduce((sum, p) => sum + p, 0); + } + + protected prUrlFor(status: RepositoryStatus): string | undefined { + return status.pullRequests?.[0]?.htmlUrl ?? undefined; + } + + protected downloadCsv(): void { const slug = this.courseContext.activeSlug(); - if (!slug || !this.text.trim()) { - return; + if (slug) { + window.location.href = `/api/${slug}/grades/csv`; + } + } + + protected clearFilters(): void { + this.search = ''; + this.searchTerm.set(''); + this.onlyUngraded.set(false); + this.onlyFailing.set(false); + } + + protected readonly filtered = computed( + () => this.searchTerm().trim().length > 0 || this.onlyUngraded() || this.onlyFailing(), + ); + + private compare(a: RepositoryStatus, b: RepositoryStatus, key: SortKey): number { + switch (key) { + case 'repository': + return (a.repository ?? '').localeCompare(b.repository ?? ''); + case 'runs': + return (a.workflowRuns?.count ?? 0) - (b.workflowRuns?.count ?? 0); + case 'total': + return (this.totalFor(a.repository) ?? -1) - (this.totalFor(b.repository) ?? -1); + default: + return (a.neptun ?? '').localeCompare(b.neptun ?? ''); } - this.client.addNote({ text: this.text }, slug).subscribe(() => { - this.text = ''; - this.reload(); - }); } } diff --git a/ahk-frontend/src/app/features/login/login.html b/ahk-frontend/src/app/features/login/login.html index 5e1aacac..f8158015 100644 --- a/ahk-frontend/src/app/features/login/login.html +++ b/ahk-frontend/src/app/features/login/login.html @@ -1,26 +1,64 @@ - + diff --git a/ahk-frontend/src/app/features/login/login.scss b/ahk-frontend/src/app/features/login/login.scss index 94e9074d..eaf0da14 100644 --- a/ahk-frontend/src/app/features/login/login.scss +++ b/ahk-frontend/src/app/features/login/login.scss @@ -1,61 +1,132 @@ +/* eduID's own blue, kept local to this screen — it is a foreign accent, used only on the federated login + button and nowhere else in the AUT palette. */ +:host { + --eduid: #0068ad; + --eduid-deep: #024f83; +} + .login { - max-width: 20rem; - margin: 4rem auto; + max-width: 23rem; + margin: 0 auto; + padding: 4rem 1.25rem; +} + +.mark { display: flex; flex-direction: column; - gap: 1rem; + gap: 0.875rem; + margin-bottom: 1.5rem; - h1 { - font-size: 1.4rem; - margin: 0; + .logo { + display: block; + width: 100%; + max-width: 17rem; + height: auto; } +} - form { - display: flex; - flex-direction: column; - gap: 0.75rem; +.product { + font-size: 1rem; +} + +h2 { + font-size: 1.125rem; +} + +.lede { + margin-bottom: 1.25rem; + font-size: 0.8125rem; +} + +/* eduID login button. The official prescription is a saturated blue block; this is the sanctioned lighter + variant — white surface, eduID-blue border, the real eduID logo, and the action word in eduID blue — so it + sits with the crimson AUT chrome while staying unmistakably eduID. */ +.eduid-btn { + display: flex; + align-items: stretch; + width: 100%; + padding: 0; + border: 1px solid var(--eduid); + border-radius: var(--radius); + background: var(--surface); + cursor: pointer; + overflow: hidden; + + .eduid-logo { + flex: none; + height: 1.5rem; + width: auto; + align-self: center; + margin: 0.625rem 0.875rem; } - label { + .eduid-label { + flex: 1 1 auto; display: flex; - flex-direction: column; - gap: 0.25rem; - font-size: 0.9rem; + align-items: center; + justify-content: center; + padding: 0.625rem 1rem; + border-left: 1px solid color-mix(in srgb, var(--eduid) 30%, var(--rule)); + font-family: var(--font-ui); + font-size: 0.9375rem; + font-weight: bold; + letter-spacing: 0.02em; + color: var(--eduid); } - input { - padding: 0.5rem; - border: 1px solid #cbd5e1; - border-radius: 4px; + &:hover { + background: color-mix(in srgb, var(--eduid) 6%, var(--surface)); + border-color: var(--eduid-deep); } - button { - padding: 0.55rem; - border: 0; - border-radius: 4px; - background: #2563eb; - color: #fff; - cursor: pointer; - - &:disabled { - opacity: 0.6; - cursor: default; - } - - &.oidc { - background: #475569; - } + &:hover .eduid-label { + color: var(--eduid-deep); } +} - .error { - color: #dc2626; - font-size: 0.85rem; - margin: 0; +/* Quiet, prose-style link to reveal the local form — it must not compete with the eduID button. */ +.linkish { + display: inline-block; + margin-top: 1rem; + border: 0; + background: none; + padding: 0; + font: inherit; + font-size: 0.8125rem; + color: var(--link); + cursor: pointer; + text-decoration: underline; + + &:hover { + color: var(--link-hover); } +} - .divider { - text-align: center; - color: #94a3b8; - font-size: 0.8rem; +.divider { + display: flex; + align-items: center; + gap: 0.75rem; + margin: 1.25rem 0; + color: var(--ink-3); + font-family: var(--font-ui); + font-size: 0.625rem; + letter-spacing: 0.12em; + text-transform: uppercase; + + &::before, + &::after { + content: ''; + flex: 1; + height: 1px; + background: var(--rule); } } + +.btn.wide { + width: 100%; + justify-content: center; +} + +.notice { + margin-bottom: 0.875rem; +} diff --git a/ahk-frontend/src/app/features/login/login.ts b/ahk-frontend/src/app/features/login/login.ts index 6590ac2e..fd16c59d 100644 --- a/ahk-frontend/src/app/features/login/login.ts +++ b/ahk-frontend/src/app/features/login/login.ts @@ -4,7 +4,11 @@ import { ActivatedRoute, Router } from '@angular/router'; import { AuthService } from '../../core/auth/auth.service'; -/** Local username/password login plus an "OIDC login" entry point (navigates to the backend challenge). */ +/** + * Sign-in screen. eduID (the institutional federated login) is the primary and expected path, so it leads. + * Local username/password is for the handful of administrator-issued accounts, so it stays collapsed behind a + * link and only appears when asked for. + */ @Component({ selector: 'app-login', imports: [FormsModule], @@ -21,34 +25,33 @@ export class Login { protected readonly error = signal(null); protected readonly busy = signal(false); + /** The local username/password form is hidden until the user says they have no eduID account. */ + protected readonly showLocal = signal(false); + + protected loginWithEduId(): void { + // Full-page navigation so the browser follows the OIDC redirect chain; proxied to the backend in dev. + const returnUrl = this.route.snapshot.queryParamMap.get('returnUrl') ?? ''; + window.location.href = `/api/auth/external/challenge?returnUrl=${encodeURIComponent(returnUrl)}`; + } + + protected revealLocal(): void { + this.showLocal.set(true); + } + protected submit(): void { this.error.set(null); this.busy.set(true); - this.auth.login(this.userName, this.password).subscribe((ok) => { + this.auth.login(this.userName, this.password).subscribe((failure) => { this.busy.set(false); - if (ok) { - this.router.navigateByUrl(this.landingUrl()); + if (failure) { + this.error.set(failure); } else { - this.error.set('Invalid username or password.'); + this.router.navigateByUrl(this.landingUrl()); } }); } - protected loginWithOidc(): void { - // Full-page navigation so the browser follows the OIDC redirect chain; proxied to the backend in dev. - const returnUrl = this.landingUrl(); - window.location.href = `/api/auth/external/challenge?returnUrl=${encodeURIComponent(returnUrl)}`; - } - private landingUrl(): string { - const returnUrl = this.route.snapshot.queryParamMap.get('returnUrl'); - if (returnUrl) { - return returnUrl; - } - if (this.auth.isAdmin()) { - return '/admin/courses'; - } - const first = this.auth.courses()[0]; - return first ? `/${first.slug}/dashboard` : '/login'; + return this.route.snapshot.queryParamMap.get('returnUrl') ?? this.auth.landingUrl(); } } diff --git a/ahk-frontend/src/app/features/no-access/no-access.html b/ahk-frontend/src/app/features/no-access/no-access.html new file mode 100644 index 00000000..e04727c3 --- /dev/null +++ b/ahk-frontend/src/app/features/no-access/no-access.html @@ -0,0 +1,14 @@ +
+ Signed in +

You are not assigned to a course

+

+ Your account works, but no course has been assigned to it yet, so there is nothing to show. Ask the + administrator of your course to add + {{ user()?.userName }} + as staff. +

+ +
+ +
+
diff --git a/ahk-frontend/src/app/features/no-access/no-access.scss b/ahk-frontend/src/app/features/no-access/no-access.scss new file mode 100644 index 00000000..2c7fd9cc --- /dev/null +++ b/ahk-frontend/src/app/features/no-access/no-access.scss @@ -0,0 +1,13 @@ +.no-access { + max-width: 34rem; + margin: 0 auto; + padding: 5rem 1.25rem; +} + +h1 { + margin-bottom: 0.5rem; +} + +.lede { + margin-bottom: 1.5rem; +} diff --git a/ahk-frontend/src/app/features/no-access/no-access.ts b/ahk-frontend/src/app/features/no-access/no-access.ts new file mode 100644 index 00000000..a8457365 --- /dev/null +++ b/ahk-frontend/src/app/features/no-access/no-access.ts @@ -0,0 +1,21 @@ +import { Component, inject } from '@angular/core'; +import { Router } from '@angular/router'; + +import { AuthService } from '../../core/auth/auth.service'; + +/** Landing for a signed-in user who is not assigned to any course yet, so the guards have nowhere to send them. */ +@Component({ + selector: 'app-no-access', + templateUrl: './no-access.html', + styleUrl: './no-access.scss', +}) +export class NoAccess { + private readonly auth = inject(AuthService); + private readonly router = inject(Router); + + protected readonly user = this.auth.currentUser; + + protected logout(): void { + this.auth.logout().subscribe(() => this.router.navigate(['/login'])); + } +} diff --git a/ahk-frontend/src/app/layout/shell/shell.html b/ahk-frontend/src/app/layout/shell/shell.html index c9f71293..b6232cbe 100644 --- a/ahk-frontend/src/app/layout/shell/shell.html +++ b/ahk-frontend/src/app/layout/shell/shell.html @@ -1,36 +1,70 @@ + +
- AHK + + + AHK + - @if (courseContext.activeCourse(); as course) { - {{ course.name }} - } - - +
+ + +
- @if (isAdmin()) { - Admin - } @if (user(); as u) { - {{ u.displayName || u.userName }} + + {{ u.displayName || u.userName }} + @if (isAdmin()) { + Site admin + } + } - +
-
- -
+
+ + +
+ +
+
diff --git a/ahk-frontend/src/app/layout/shell/shell.scss b/ahk-frontend/src/app/layout/shell/shell.scss index aee01b24..3ea018aa 100644 --- a/ahk-frontend/src/app/layout/shell/shell.scss +++ b/ahk-frontend/src/app/layout/shell/shell.scss @@ -1,47 +1,212 @@ +:host { + display: block; + min-height: 100vh; +} + +.skip { + position: absolute; + left: -9999px; +} + +.skip:focus { + left: 0.5rem; + top: 0.5rem; + z-index: 10; + background: var(--surface); + padding: 0.5rem 0.75rem; + border-radius: var(--radius); +} + +/* Dark band carrying the department logo, as on aut.bme.hu. Its own tokens, because + these are the one place the palette runs inverted. */ +:host { + --topbar: #1a1a1a; + --topbar-ink: #d8d6d2; + --topbar-line: #3a3a3a; + --topbar-field: #2b2b2b; +} + .topbar { display: flex; align-items: center; - gap: 1rem; - padding: 0.75rem 1.25rem; - background: #1f2937; - color: #f9fafb; + gap: 1.25rem; + flex-wrap: wrap; + padding: 0.625rem 1.25rem; + background: var(--topbar); + color: var(--topbar-ink); + border-bottom: 3px solid var(--brand-dark); +} - .brand { - font-weight: 700; - letter-spacing: 0.05em; +.brand { + display: flex; + align-items: center; + gap: 0.75rem; + color: #fff; + + &:hover { + text-decoration: none; } - .course { - font-weight: 600; - opacity: 0.9; + .logo { + display: block; + height: 26px; + width: auto; } - .switcher { - display: flex; - align-items: center; - gap: 0.4rem; - font-size: 0.9rem; + /* Hairline rule separating the department mark from the product name. */ + .product { + padding-left: 0.75rem; + border-left: 1px solid var(--topbar-line); + font-family: var(--font-display); + font-size: 1.125rem; + letter-spacing: 0.08em; + color: #fff; } +} - .spacer { - flex: 1 1 auto; +.switcher { + display: flex; + align-items: center; + gap: 0.5rem; + + label { + font-family: var(--font-ui); + font-size: 0.625rem; + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--topbar-ink); } - .user { - opacity: 0.85; + select { + width: auto; + max-width: 18rem; + background: var(--topbar-field); + border-color: var(--topbar-line); + color: #fff; } +} - a.link, - a.link:visited { - color: #93c5fd; - text-decoration: none; +.spacer { + flex: 1 1 auto; +} + +.who { + display: flex; + align-items: center; + gap: 0.5rem; + font-size: 0.8125rem; + + .name { + color: var(--topbar-ink); + } +} + +.btn.on-ink { + color: var(--topbar-ink); + + &:hover { + background: var(--topbar-field); + border-color: var(--topbar-line); + color: #fff; + } +} + +.frame { + display: flex; + align-items: stretch; + min-height: calc(100vh - 3.125rem); +} + +.rail { + flex: none; + width: 13rem; + padding: 1.25rem 0.75rem; + border-right: 1px solid var(--rule); + background: var(--surface); + + /* aut.bme.hu marks the current section with a 3px crimson edge on the nav item. + The rail is vertical, so the edge is on the left; it moves to the bottom at the + narrow breakpoint below, where the rail turns horizontal and matches #mainNavBar. */ + a { + display: block; + padding: 0.375rem 0.625rem; + border-left: 3px solid transparent; + color: var(--ink-2); + font-size: 0.8125rem; + + &:hover { + background: var(--surface-2); + color: var(--brand); + text-decoration: none; + } + + &.active { + border-left-color: var(--brand-dark); + background: var(--accent-wash); + color: var(--brand); + font-weight: bold; + } } +} + +.rail-title { + display: block; + font-family: var(--font-ui); + font-size: 0.625rem; + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--ink-3); + padding: 0 0.625rem; + margin-bottom: 0.5rem; - button { - cursor: pointer; + /* Every group after the first needs air above it. */ + & ~ .rail-title { + margin-top: 1.5rem; } } +.rail-note { + margin: 0.5rem 0.625rem 0; + font-size: 0.75rem; + line-height: 1.4; + color: var(--warn); +} + .content { + flex: 1 1 auto; padding: 1.5rem; + min-width: 0; +} + +@media (max-width: 52rem) { + .frame { + flex-direction: column; + } + + .rail { + width: auto; + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.25rem; + padding: 0.625rem 1rem; + border-right: 0; + border-bottom: 1px solid var(--rule); + + /* Horizontal now, so the crimson edge moves to the bottom — aut.bme.hu's + #mainNavBar treatment exactly. */ + a { + border-left: 0; + border-bottom: 3px solid transparent; + + &.active { + border-bottom-color: var(--brand-dark); + } + } + } + + .rail-note { + flex: 1 1 100%; + margin: 0.25rem 0 0; + } } diff --git a/ahk-frontend/src/app/layout/shell/shell.ts b/ahk-frontend/src/app/layout/shell/shell.ts index 1912f010..1c368ebd 100644 --- a/ahk-frontend/src/app/layout/shell/shell.ts +++ b/ahk-frontend/src/app/layout/shell/shell.ts @@ -1,13 +1,17 @@ -import { Component, inject } from '@angular/core'; -import { Router, RouterLink, RouterOutlet } from '@angular/router'; +import { Component, computed, inject } from '@angular/core'; +import { Router, RouterLink, RouterLinkActive, RouterOutlet } from '@angular/router'; import { AuthService } from '../../core/auth/auth.service'; import { CourseContextService } from '../../core/course/course-context.service'; -/** Authenticated app frame: header with the active course, a course switcher, admin link and logout. */ +/** + * Authenticated app frame: a topbar carrying identity and the course switcher, and a rail whose contents + * depend on where you are — course screens inside a course, site screens under /admin. Admins can reach every + * course from the switcher, so the same frame serves both jobs without a separate "admin mode". + */ @Component({ selector: 'app-shell', - imports: [RouterOutlet, RouterLink], + imports: [RouterOutlet, RouterLink, RouterLinkActive], templateUrl: './shell.html', styleUrl: './shell.scss', }) @@ -20,8 +24,16 @@ export class Shell { protected readonly isAdmin = this.auth.isAdmin; protected readonly courses = this.auth.courses; - protected switch(slug: string): void { - void this.router.navigate([slug, 'dashboard']); + protected readonly activeSlug = this.courseContext.activeSlug; + protected readonly activeCourse = this.courseContext.activeCourse; + + /** True on the site-admin screens, which have no course context. */ + protected readonly inAdmin = computed(() => this.activeSlug() === null); + + protected switchCourse(slug: string): void { + if (slug) { + void this.router.navigate([slug, 'dashboard']); + } } protected logout(): void { diff --git a/ahk-frontend/src/app/shared/health-chain/health-chain.html b/ahk-frontend/src/app/shared/health-chain/health-chain.html new file mode 100644 index 00000000..950cd172 --- /dev/null +++ b/ahk-frontend/src/app/shared/health-chain/health-chain.html @@ -0,0 +1,35 @@ +
+ @for (c of checks(); track c.checkId) { + + } @empty { +

No checks are registered.

+ } +
+ +@if (detailed()) { +
+ @for (c of checks(); track c.checkId) { +
+ + {{ c.title }} +
+
+ {{ c.message }} + @if (c.remediation && c.status !== 'Healthy') { + {{ c.remediation }} + } +
+ } +
+} diff --git a/ahk-frontend/src/app/shared/health-chain/health-chain.scss b/ahk-frontend/src/app/shared/health-chain/health-chain.scss new file mode 100644 index 00000000..50075eaf --- /dev/null +++ b/ahk-frontend/src/app/shared/health-chain/health-chain.scss @@ -0,0 +1,110 @@ +/* The one loud element in the product: the integration drawn as a chain of chevrons, each link tinted by its + check. Links overlap by the width of their notch so they read as one continuous run. */ + +.chain { + display: flex; + flex-wrap: wrap; + align-items: stretch; + gap: 0; + font-family: var(--font-ui); +} + +.link { + --notch: 0.6rem; + + position: relative; + display: flex; + flex-direction: column; + justify-content: center; + gap: 0.0625rem; + min-width: 8.5rem; + padding: 0.375rem 0.75rem 0.375rem calc(0.75rem + var(--notch)); + margin-right: calc(var(--notch) * -1 + 2px); + background: var(--idle-wash); + color: var(--ink-2); + clip-path: polygon(0 0, calc(100% - var(--notch)) 0, 100% 50%, calc(100% - var(--notch)) 100%, 0 100%, var(--notch) 50%); +} + +/* The run has a flat head, so the first link does not point into empty space. */ +.link:first-child { + padding-left: 0.75rem; + clip-path: polygon(0 0, calc(100% - var(--notch)) 0, 100% 50%, calc(100% - var(--notch)) 100%, 0 100%); +} + +.link.ok { + background: var(--ok-wash); + color: var(--ok); +} + +.link.warn { + background: var(--warn-wash); + color: var(--warn); +} + +.link.bad { + background: var(--bad-wash); + color: var(--bad); +} + +.link-title { + font-size: 0.6875rem; + letter-spacing: 0.06em; + text-transform: uppercase; + opacity: 0.75; +} + +.link-state { + font-size: 0.75rem; + font-weight: 600; +} + +/* Below ~40rem the chevrons would be unreadable; stack them as plain bars instead. */ +@media (max-width: 40rem) { + .link, + .link:first-child { + flex: 1 1 100%; + margin-right: 0; + margin-bottom: 2px; + padding-left: 0.75rem; + clip-path: none; + border-left: 3px solid currentcolor; + } +} + +.detail { + display: grid; + grid-template-columns: minmax(9rem, auto) 1fr; + gap: 0.4375rem 1rem; + margin: 1rem 0 0; + font-size: 0.8125rem; +} + +.detail dt { + display: flex; + align-items: center; + gap: 0.4375rem; + font-family: var(--font-ui); + color: var(--ink-2); +} + +.detail dd { + margin: 0; +} + +.detail .fix { + display: block; + color: var(--ink-2); + font-size: 0.75rem; + margin-top: 0.125rem; +} + +@media (max-width: 34rem) { + .detail { + grid-template-columns: 1fr; + gap: 0.125rem; + } + + .detail dd { + margin-bottom: 0.625rem; + } +} diff --git a/ahk-frontend/src/app/shared/health-chain/health-chain.ts b/ahk-frontend/src/app/shared/health-chain/health-chain.ts new file mode 100644 index 00000000..89a5b809 --- /dev/null +++ b/ahk-frontend/src/app/shared/health-chain/health-chain.ts @@ -0,0 +1,45 @@ +import { Component, input } from '@angular/core'; + +import { HealthCheckResult, HealthStatus } from '../../api/api-client'; + +/** + * A course's health drawn as the pipeline it describes: webhook in, credentials, callback out. Each link is + * tinted by its check, so a glance says *which* part of the integration is broken rather than only that + * something is. Set `detailed` to print each check's message and next step underneath. + */ +@Component({ + selector: 'app-health-chain', + templateUrl: './health-chain.html', + styleUrl: './health-chain.scss', +}) +export class HealthChain { + readonly checks = input.required(); + readonly detailed = input(false); + + /** Maps a status onto the shared status classes (ok / warn / bad / idle). */ + protected tone(status: HealthStatus | undefined): string { + switch (status) { + case 'Healthy': + return 'ok'; + case 'Warning': + return 'warn'; + case 'Failed': + return 'bad'; + default: + return 'idle'; + } + } + + protected label(status: HealthStatus | undefined): string { + switch (status) { + case 'Healthy': + return 'Passing'; + case 'Warning': + return 'Needs attention'; + case 'Failed': + return 'Failing'; + default: + return 'Not set up'; + } + } +} diff --git a/ahk-frontend/src/index.html b/ahk-frontend/src/index.html index 8c0eb582..472948da 100644 --- a/ahk-frontend/src/index.html +++ b/ahk-frontend/src/index.html @@ -2,7 +2,7 @@ - AhkFrontend + AHK — Automated homework evaluation diff --git a/ahk-frontend/src/styles.scss b/ahk-frontend/src/styles.scss index 90d4ee00..8bb04e68 100644 --- a/ahk-frontend/src/styles.scss +++ b/ahk-frontend/src/styles.scss @@ -1 +1,554 @@ -/* You can add global styles to this file, and also import other style files */ +/* ============================================================================= + AHK portal — global design system, in the BME AUT visual identity. + Component stylesheets are scoped by Angular, so everything shared lives here: + tokens, base elements, and the handful of classes the screens compose from + (page, card, field, btn, table, badge). + + The palette and typography come from aut.bme.hu, so the portal reads as a + department system rather than a standalone tool. Provenance of every value is + recorded in brand/README.md, next to the logo masters. + + Type does three jobs and uses three faces: Georgia for headings (the AUT + house style), Verdana for labels and controls, and monospace for machine + identifiers — slugs, organizations, repositories, Neptun codes, tokens — + because comparing those character by character is the actual work. + ============================================================================= */ + +:root { + /* --- BME AUT identity -------------------------------------------------- + Three different reds, deliberately. Collapsing them loses information: + --brand marks headings and primary actions, --link is for navigation, and + --bad means something is broken. aut.bme.hu makes the same distinction. */ + --brand: #a4001e; /* aut.bme.hu heading + accent crimson */ + --brand-deep: #900028; /* the logo's own crimson (PANTONE 202) */ + --brand-dark: #88000f; /* aut.bme.hu active-navigation marker */ + + /* Kept as --accent so every component that already reads it follows along. */ + --accent: var(--brand); + --accent-ink: #7d0017; + --accent-wash: #f6e6e9; + + /* Navy, not crimson: aut.bme.hu sets a[href] { color:#074371 }. */ + --link: #074371; + --link-hover: #052f50; + + /* Warm neutrals from aut.bme.hu's grid views. */ + --parchment: #dbd9c0; + --parchment-2: #f7f5dc; + + /* Ink + paper */ + --ink: #1a1a1a; + --ink-2: #4a4a4a; + --ink-3: #767676; /* not AUT's #999, which is 2.8:1 on white and fails WCAG AA */ + --paper: #dedddb; /* AUT's #ddd, warmed to sit with the parchment */ + --surface: #ffffff; + --surface-2: #f7f6f2; + --rule: #d5d3cc; + --rule-strong: #bcb9ae; + + /* Status. These carry the meaning in this product, so they are the loud ones. + --bad is AUT's own error red, browner and darker than --brand, so a failing + badge cannot be mistaken for brand chrome. */ + --ok: #1f7a4d; + --ok-wash: #e2f2e8; + --warn: #a86414; + --warn-wash: #f8eddc; + --bad: #801b1b; + --bad-wash: #ffcfcf; + --bad-rule: #e5a3a3; + --idle: #767676; + --idle-wash: #ececea; + + --font-display: Georgia, 'Times New Roman', Times, serif; + --font-ui: Verdana, Arial, Helvetica, sans-serif; + --font-mono: ui-monospace, 'Cascadia Mono', 'JetBrains Mono', 'SF Mono', Consolas, monospace; + + --radius: 3px; + --shadow: 0 1px 2px rgb(26 26 26 / 6%), 0 1px 12px rgb(26 26 26 / 4%); + + color-scheme: light; +} + +* { + box-sizing: border-box; +} + +html, +body { + margin: 0; + padding: 0; +} + +body { + background: var(--paper); + color: var(--ink); + font-family: var(--font-ui); + + /* Verdana runs wide, so the base drops a step to keep the dense tables legible. + aut.bme.hu does the same thing with font-size: 70%. */ + font-size: 0.8125rem; + line-height: 1.5; + -webkit-font-smoothing: antialiased; +} + +/* Crimson serif at normal weight — the single rule that makes a page read as AUT. */ +h1, +h2, +h3 { + font-family: var(--font-display); + font-weight: normal; + color: var(--brand); + margin: 0; +} + +h1 { + font-size: 1.5rem; +} + +h2 { + font-size: 1.125rem; +} + +h3 { + font-size: 0.9375rem; +} + +a { + color: var(--link); + text-decoration: none; +} + +a:hover { + color: var(--link-hover); + text-decoration: underline; +} + +/* A link that is a heading keeps the heading's crimson (AUT: h3 a[href] { color:#a4001e }). */ +h1 a, +h2 a, +h3 a { + color: var(--brand); +} + +:focus-visible { + outline: 2px solid var(--brand); + outline-offset: 2px; +} + +/* ---- Page scaffolding ------------------------------------------------- */ + +.page { + max-width: 74rem; +} + +.page-head { + display: flex; + align-items: flex-start; + gap: 1rem; + flex-wrap: wrap; + margin-bottom: 1.25rem; +} + +.page-head .grow { + flex: 1 1 16rem; +} + +/* Small tracked label above a heading or beside a value. */ +.eyebrow { + display: block; + font-family: var(--font-ui); + font-size: 0.625rem; + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--ink-3); + margin-bottom: 0.25rem; +} + +.lede { + color: var(--ink-2); + margin: 0.375rem 0 0; + max-width: 56ch; +} + +.muted { + color: var(--ink-2); +} + +.mono { + font-family: var(--font-mono); +} + +/* ---- Card ------------------------------------------------------------- */ + +.card { + background: var(--surface); + border: 1px solid var(--rule); + border-radius: var(--radius); + box-shadow: var(--shadow); + margin-bottom: 1.25rem; +} + +.card > header { + display: flex; + align-items: center; + gap: 0.75rem; + flex-wrap: wrap; + padding: 0.875rem 1.125rem; + border-bottom: 1px solid var(--rule); +} + +.card > header .grow { + flex: 1 1 auto; +} + +.card > header p { + margin: 0.125rem 0 0; + color: var(--ink-2); + font-size: 0.8125rem; +} + +.card-body { + padding: 1.125rem; +} + +.card-body > :first-child { + margin-top: 0; +} + +.card-body > :last-child { + margin-bottom: 0; +} + +.card-foot { + display: flex; + align-items: center; + gap: 0.75rem; + flex-wrap: wrap; + padding: 0.875rem 1.125rem; + border-top: 1px solid var(--rule); + background: var(--surface-2); +} + +/* ---- Forms ------------------------------------------------------------ */ + +.field { + display: flex; + flex-direction: column; + gap: 0.3125rem; + margin-bottom: 0.875rem; +} + +.field > label { + font-family: var(--font-ui); + font-size: 0.625rem; + font-weight: bold; + letter-spacing: 0.1em; + text-transform: uppercase; + color: var(--ink-2); +} + +.field .hint { + font-size: 0.75rem; + color: var(--ink-2); +} + +.field-row { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); + gap: 0 1rem; +} + +/* Monospace, because these hold identifiers — slugs, organizations, tokens. */ +input[type='text'], +input[type='password'], +input[type='email'], +input[type='number'], +input[type='search'], +select, +textarea { + font: inherit; + font-family: var(--font-mono); + font-size: 0.8125rem; + padding: 0.4375rem 0.5625rem; + color: var(--ink); + background: var(--surface); + border: 1px solid var(--rule-strong); + border-radius: var(--radius); + width: 100%; + min-width: 0; +} + +input:focus, +select:focus, +textarea:focus { + border-color: var(--accent); + outline: 1px solid var(--accent); + outline-offset: -1px; +} + +input::placeholder { + color: var(--ink-3); +} + +input:disabled, +select:disabled { + background: var(--surface-2); + color: var(--ink-2); +} + +input.ng-invalid.ng-touched { + border-color: var(--bad); +} + +.check { + display: flex; + align-items: center; + gap: 0.5rem; + font-size: 0.8125rem; +} + +.check input { + width: auto; + accent-color: var(--accent); +} + +/* ---- Buttons ---------------------------------------------------------- */ + +.btn { + display: inline-flex; + align-items: center; + gap: 0.375rem; + font-family: var(--font-ui); + font-size: 0.6875rem; + letter-spacing: 0.02em; + padding: 0.4375rem 0.75rem; + border: 1px solid var(--rule-strong); + border-radius: var(--radius); + background: var(--surface); + color: var(--ink); + cursor: pointer; + white-space: nowrap; + text-decoration: none; +} + +.btn:hover:not(:disabled) { + background: var(--surface-2); + border-color: var(--ink-3); + text-decoration: none; +} + +.btn:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.btn.primary { + background: var(--accent); + border-color: var(--accent); + color: #fff; +} + +.btn.primary:hover:not(:disabled) { + background: var(--accent-ink); + border-color: var(--accent-ink); +} + +.btn.danger { + color: var(--bad); + border-color: color-mix(in srgb, var(--bad) 35%, var(--rule)); +} + +.btn.danger:hover:not(:disabled) { + background: var(--bad-wash); + border-color: var(--bad); +} + +.btn.quiet { + border-color: transparent; + background: transparent; + color: var(--ink-2); +} + +.btn.quiet:hover:not(:disabled) { + background: var(--surface-2); + border-color: var(--rule); + color: var(--ink); +} + +.btn-row { + display: flex; + align-items: center; + gap: 0.5rem; + flex-wrap: wrap; +} + +/* ---- Tables ----------------------------------------------------------- */ + +.table-wrap { + overflow-x: auto; +} + +table.data { + width: 100%; + border-collapse: collapse; + font-size: 0.8125rem; +} + +/* Parchment header band — the most recognisable AUT table cue (.gridViewHeader). */ +table.data th { + font-family: var(--font-ui); + font-size: 0.625rem; + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--ink); + font-weight: bold; + text-align: left; + padding: 0.5rem 0.75rem; + background: var(--parchment); + border-bottom: 1px solid var(--rule-strong); + white-space: nowrap; +} + +table.data td { + padding: 0.5625rem 0.75rem; + border-bottom: 1px solid var(--rule); + vertical-align: top; +} + +table.data tbody tr:last-child td { + border-bottom: 0; +} + +table.data tbody tr:hover td { + background: var(--surface-2); +} + +table.data th.num, +table.data td.num { + text-align: right; + font-variant-numeric: tabular-nums; + white-space: nowrap; +} + +table.data td.actions { + text-align: right; + white-space: nowrap; +} + +.empty { + padding: 2rem 1.125rem; + text-align: center; + color: var(--ink-2); +} + +/* ---- Badges + status -------------------------------------------------- */ + +.badge { + display: inline-flex; + align-items: center; + gap: 0.25rem; + font-family: var(--font-ui); + font-size: 0.625rem; + letter-spacing: 0.04em; + padding: 0.0625rem 0.375rem; + border: 1px solid transparent; + border-radius: 2px; + background: var(--idle-wash); + color: var(--ink-2); + white-space: nowrap; +} + +.badge.ok { + background: var(--ok-wash); + color: var(--ok); +} + +.badge.warn { + background: var(--warn-wash); + color: var(--warn); +} + +.badge.bad { + background: var(--bad-wash); + border-color: var(--bad-rule); + color: var(--bad); +} + +.badge.accent { + background: var(--accent-wash); + color: var(--accent-ink); +} + +/* Status dot, for inline use in lists. */ +.dot { + display: inline-block; + width: 0.5rem; + height: 0.5rem; + border-radius: 50%; + background: var(--idle); + flex: none; +} + +.dot.ok { + background: var(--ok); +} + +.dot.warn { + background: var(--warn); +} + +.dot.bad { + background: var(--bad); +} + +/* ---- Notices ---------------------------------------------------------- */ + +.notice { + display: flex; + align-items: flex-start; + gap: 0.5rem; + padding: 0.625rem 0.875rem; + border: 1px solid var(--rule-strong); + border-left-width: 3px; + border-radius: var(--radius); + font-size: 0.8125rem; + margin-bottom: 1rem; +} + +/* Matches aut.bme.hu's .errorBox: dark red on a pale wash, with its own rule colour. */ +.notice.error { + border-color: var(--bad-rule); + border-left-color: var(--bad); + background: var(--bad-wash); + color: var(--bad); + font-weight: bold; +} + +.notice.success { + border-color: var(--ok); + background: var(--ok-wash); + color: var(--ok); +} + +.notice.warn { + border-color: var(--warn); + background: var(--warn-wash); + color: var(--warn); +} + +.notice.info { + border-color: var(--accent); + background: var(--accent-wash); + color: var(--accent-ink); +} + +/* ---- Reduced motion --------------------------------------------------- */ + +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + transition-duration: 0.01ms !important; + } +} From febd940bbd0b29915be5017bf0326d4d0a939d5c Mon Sep 17 00:00:00 2001 From: Bence Kovari Date: Sat, 25 Jul 2026 17:09:46 +0200 Subject: [PATCH 03/19] feat: add assignment management feature for courses - Implemented assignments.html for displaying and managing assignments. - Created assignments.scss for styling the assignments page. - Developed assignments.ts to handle assignment logic, including creation, editing, and loading assignments. - Added invite.html for students to accept assignments via invite links. - Created invite.scss for styling the invite acceptance page. - Developed invite.ts to manage the invite acceptance flow and GitHub username input. - Implemented my-assignments.html to display a student's repositories across courses. - Created my-assignments.scss for styling the student's assignments page. - Developed my-assignments.ts to handle loading and resending invitations for student repositories. --- .github/workflows/ahk-web-deploy.yaml | 181 +++ .../Ahk.Web.Data/ApplicationDbContext.cs | 45 + .../Ahk.Web.Data/Entities/ApplicationUser.cs | 10 + .../Ahk.Web.Data/Entities/Assignment.cs | 46 + .../Entities/AssignmentAcceptance.cs | 52 + .../20260724154747_Assignments.Designer.cs | 1006 ++++++++++++++++ .../Migrations/20260724154747_Assignments.cs | 137 +++ .../ApplicationDbContextModelSnapshot.cs | 152 +++ .../Ahk.Web.Data/Seed/DevDataSeeder.cs | 32 + ahk-backend/Ahk.Web.Data/TokenGenerator.cs | 17 + .../Ahk.Web.Server.Tests/ApiSmokeTests.cs | 42 +- .../AssignmentInviteTests.cs | 300 +++++ .../AssignmentScopingTests.cs | 109 ++ .../StudentAssignmentTests.cs | 210 ++++ .../Admin/CoursesAdminController.cs | 6 +- .../Ahk.Web.Server/Auth/AuthController.cs | 2 + .../Auth/Dto/CurrentUserResponse.cs | 9 + .../Ahk.Web.Server/Auth/ProfileController.cs | 117 ++ .../Courses/AssignmentInviteController.cs | 97 ++ .../Courses/AssignmentsController.cs | 208 ++++ .../Courses/Dto/AssignmentDto.cs | 101 ++ ahk-backend/Ahk.Web.Server/Program.cs | 9 + .../Properties/PublishProfiles/Mezga.pubxml | 22 + .../Students/MyAssignmentsController.cs | 83 ++ ahk-backend/Ahk.Web.Server/app_offline.htm | 41 + .../Assignments/AssignmentInviteService.cs | 319 +++++ .../Assignments/AssignmentService.cs | 252 ++++ .../Assignments/StudentAssignmentService.cs | 233 ++++ .../Courses/WebhookTokenService.cs | 12 +- .../GitHub/CourseGitHubAppTokenProvider.cs | 203 ++++ .../GitHub/GitHubApiDefaults.cs | 32 + .../GitHub/GitHubOperationException.cs | 43 + .../GitHub/GitHubRepositoryService.cs | 262 +++++ .../GitHubAppInstallationHealthCheck.cs | 123 ++ .../ServiceCollectionExtensions.cs | 32 + ahk-backend/README.md | 46 +- ahk-backend/docs/github-app.md | 167 +++ ahk-frontend/src/app/api/api-client.ts | 1047 ++++++++++++++++- ahk-frontend/src/app/app.routes.ts | 21 +- .../src/app/core/auth/auth.service.ts | 22 +- ahk-frontend/src/app/core/clipboard.ts | 35 + .../course/assignments/assignments.html | 248 ++++ .../course/assignments/assignments.scss | 82 ++ .../course/assignments/assignments.ts | 260 ++++ .../src/app/features/invite/invite.html | 182 +++ .../src/app/features/invite/invite.scss | 56 + .../src/app/features/invite/invite.ts | 148 +++ .../src/app/features/my/my-assignments.html | 124 ++ .../src/app/features/my/my-assignments.scss | 89 ++ .../src/app/features/my/my-assignments.ts | 103 ++ .../src/app/features/no-access/no-access.html | 14 - .../src/app/features/no-access/no-access.scss | 13 - .../src/app/features/no-access/no-access.ts | 21 - ahk-frontend/src/app/layout/shell/shell.html | 1 + 54 files changed, 7142 insertions(+), 82 deletions(-) create mode 100644 .github/workflows/ahk-web-deploy.yaml create mode 100644 ahk-backend/Ahk.Web.Data/Entities/Assignment.cs create mode 100644 ahk-backend/Ahk.Web.Data/Entities/AssignmentAcceptance.cs create mode 100644 ahk-backend/Ahk.Web.Data/Migrations/20260724154747_Assignments.Designer.cs create mode 100644 ahk-backend/Ahk.Web.Data/Migrations/20260724154747_Assignments.cs create mode 100644 ahk-backend/Ahk.Web.Data/TokenGenerator.cs create mode 100644 ahk-backend/Ahk.Web.Server.Tests/AssignmentInviteTests.cs create mode 100644 ahk-backend/Ahk.Web.Server.Tests/AssignmentScopingTests.cs create mode 100644 ahk-backend/Ahk.Web.Server.Tests/StudentAssignmentTests.cs create mode 100644 ahk-backend/Ahk.Web.Server/Auth/ProfileController.cs create mode 100644 ahk-backend/Ahk.Web.Server/Courses/AssignmentInviteController.cs create mode 100644 ahk-backend/Ahk.Web.Server/Courses/AssignmentsController.cs create mode 100644 ahk-backend/Ahk.Web.Server/Courses/Dto/AssignmentDto.cs create mode 100644 ahk-backend/Ahk.Web.Server/Properties/PublishProfiles/Mezga.pubxml create mode 100644 ahk-backend/Ahk.Web.Server/Students/MyAssignmentsController.cs create mode 100644 ahk-backend/Ahk.Web.Server/app_offline.htm create mode 100644 ahk-backend/Ahk.Web.Services/Assignments/AssignmentInviteService.cs create mode 100644 ahk-backend/Ahk.Web.Services/Assignments/AssignmentService.cs create mode 100644 ahk-backend/Ahk.Web.Services/Assignments/StudentAssignmentService.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHub/CourseGitHubAppTokenProvider.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHub/GitHubApiDefaults.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHub/GitHubOperationException.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHub/GitHubRepositoryService.cs create mode 100644 ahk-backend/Ahk.Web.Services/Health/GitHubAppInstallationHealthCheck.cs create mode 100644 ahk-backend/docs/github-app.md create mode 100644 ahk-frontend/src/app/core/clipboard.ts create mode 100644 ahk-frontend/src/app/features/course/assignments/assignments.html create mode 100644 ahk-frontend/src/app/features/course/assignments/assignments.scss create mode 100644 ahk-frontend/src/app/features/course/assignments/assignments.ts create mode 100644 ahk-frontend/src/app/features/invite/invite.html create mode 100644 ahk-frontend/src/app/features/invite/invite.scss create mode 100644 ahk-frontend/src/app/features/invite/invite.ts create mode 100644 ahk-frontend/src/app/features/my/my-assignments.html create mode 100644 ahk-frontend/src/app/features/my/my-assignments.scss create mode 100644 ahk-frontend/src/app/features/my/my-assignments.ts delete mode 100644 ahk-frontend/src/app/features/no-access/no-access.html delete mode 100644 ahk-frontend/src/app/features/no-access/no-access.scss delete mode 100644 ahk-frontend/src/app/features/no-access/no-access.ts diff --git a/.github/workflows/ahk-web-deploy.yaml b/.github/workflows/ahk-web-deploy.yaml new file mode 100644 index 00000000..48eba0ea --- /dev/null +++ b/.github/workflows/ahk-web-deploy.yaml @@ -0,0 +1,181 @@ +name: AHK Web - build, test & deploy to Mezga + +# Manual trigger only: this deploys to the on-prem IIS server behind the BME VPN. +on: [workflow_dispatch] + +env: + DOTNET_VERSION: "10.0.x" + NODE_VERSION: "24" + BACKEND_PROJECT: ahk-backend/Ahk.Web.Server/Ahk.Web.Server.csproj + SOLUTION: ahk-backend/Ahk.Web.slnx + DATA_PROJECT: ahk-backend/Ahk.Web.Data + FRONTEND_DIR: ahk-frontend + OFFLINE_PAGE: ahk-backend/Ahk.Web.Server/app_offline.htm + MOUNT_POINT: /mnt/deploy + +jobs: + deploy: + runs-on: ubuntu-latest + # The Mezga environment holds the VPN_ADDRESS / DEPLOYMENT_PATH variables and every secret, and + # gates the run behind whatever protection rules the environment defines. + environment: Mezga + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: npm + cache-dependency-path: ${{ env.FRONTEND_DIR }}/package-lock.json + + # ---- A. Build & test (fail-fast: nothing below runs if a test fails) ---- + + - name: Backend tests + run: dotnet test ${{ env.SOLUTION }} --configuration Release + + - name: Install frontend dependencies + working-directory: ${{ env.FRONTEND_DIR }} + run: npm ci + + - name: Frontend tests + working-directory: ${{ env.FRONTEND_DIR }} + run: npx ng test --watch=false + + # ---- B. Produce artifacts ---- + + - name: Publish backend (self-contained win-x64 via Mezga profile) + run: dotnet publish ${{ env.BACKEND_PROJECT }} -p:PublishProfile=Mezga -o publish + + - name: Build frontend (production) + working-directory: ${{ env.FRONTEND_DIR }} + run: npx ng build --configuration production + + - name: Copy SPA into backend wwwroot + run: | + mkdir -p publish/wwwroot + cp -r ${{ env.FRONTEND_DIR }}/dist/ahk-frontend/browser/. publish/wwwroot/ + + - name: Stage offline page alongside the publish output + run: cp ${{ env.OFFLINE_PAGE }} publish/app_offline.htm + + - name: Generate idempotent migration script (artifact only — applied manually) + run: | + dotnet tool install --global dotnet-ef + export PATH="$PATH:$HOME/.dotnet/tools" + dotnet ef migrations script --idempotent \ + --project ${{ env.DATA_PROJECT }} \ + --startup-project ${{ env.DATA_PROJECT }} \ + -o migrate.sql + + - name: Upload migration script + uses: actions/upload-artifact@v4 + with: + name: migrate-sql + path: migrate.sql + + # ---- C. Inject production config (never committed) ---- + + - name: Inject connection string and OIDC client secret + env: + DATABASE_CONNECTIONSTRING: ${{ secrets.DATABASE_CONNECTIONSTRING }} + OIDC_CLIENTSECRET: ${{ secrets.OIDC_CLIENTSECRET }} + run: | + jq --arg cs "$DATABASE_CONNECTIONSTRING" --arg secret "$OIDC_CLIENTSECRET" \ + '.ConnectionStrings.Default = $cs | .Authentication.Oidc.ClientSecret = $secret' \ + publish/appsettings.json > publish/appsettings.json.tmp + mv publish/appsettings.json.tmp publish/appsettings.json + + # ---- D. VPN (SSTP) up ---- + + - name: Install SSTP client + run: sudo apt-get update && sudo apt-get install -y sstp-client ppp cifs-utils + + - name: Connect SSTP VPN + id: vpn + env: + VPN_ADDRESS: ${{ vars.VPN_ADDRESS }} + VPN_USER: ${{ secrets.VPN_USER }} + VPN_PASSWORD: ${{ secrets.VPN_PASSWORD }} + # Optional: PEM of the CA that signed the VPN server cert (or the self-signed cert itself). + # Set this if the endpoint does not present a publicly-trusted certificate. When unset, sstpc + # validates against the system CA store. Never use --cert-warn: that downgrades a failed + # server-certificate check to a warning and lets a MITM harvest these credentials. + VPN_CA_CERT: ${{ secrets.VPN_CA_CERT }} + run: | + CERT_ARGS=() + if [ -n "$VPN_CA_CERT" ]; then + echo "$VPN_CA_CERT" > /tmp/vpn-ca.crt + CERT_ARGS=(--ca-cert /tmp/vpn-ca.crt) + fi + sudo sstpc --log-stderr "${CERT_ARGS[@]}" \ + --user "$VPN_USER" --password "$VPN_PASSWORD" \ + "$VPN_ADDRESS" \ + usepeerdns require-mschap-v2 noauth noipdefault defaultroute refuse-eap \ + unit 0 & + # Wait (up to ~60s) for the ppp0 interface to acquire an address. + for i in $(seq 1 30); do + if ip -4 addr show ppp0 2>/dev/null | grep -q 'inet '; then + echo "VPN up:"; ip -4 addr show ppp0 + exit 0 + fi + sleep 2 + done + echo "::error::SSTP VPN did not come up within timeout" + exit 1 + + # ---- E. Mount share, swap site ---- + + - name: Mount deployment share + env: + DEPLOYMENT_PATH: ${{ vars.DEPLOYMENT_PATH }} + FILE_USER: ${{ secrets.FILE_USER }} + FILE_PASSWORD: ${{ secrets.FILE_PASSWORD }} + run: | + sudo mkdir -p "$MOUNT_POINT" + sudo mount -t cifs "$DEPLOYMENT_PATH" "$MOUNT_POINT" \ + -o username="$FILE_USER",password="$FILE_PASSWORD",vers=3.0,uid=$(id -u),gid=$(id -g) + + - name: Stop site (drop app_offline.htm) + run: | + cp "$OFFLINE_PAGE" "$MOUNT_POINT/app_offline.htm" + # Give IIS a moment to notice and release file locks before mirroring. + sleep 5 + + - name: Mirror new files (keep app_offline.htm) + run: | + ok=0 + for i in $(seq 1 10); do + if rsync -a --delete --exclude 'app_offline.htm' publish/ "$MOUNT_POINT/"; then + ok=1; break + fi + echo "rsync attempt $i failed (likely a locked file); retrying..." + sleep 2 + done + if [ "$ok" -ne 1 ]; then + echo "::error::Mirroring the deployment failed after retries" + exit 1 + fi + + - name: Wake site (remove app_offline.htm) + run: rm -f "$MOUNT_POINT/app_offline.htm" + + - name: Warm up and verify + run: curl --fail --show-error --retry 5 --retry-delay 3 https://ahk.aut.bme.hu/ + + # ---- F. Teardown (always) ---- + + - name: Unmount share + if: always() + run: sudo umount "$MOUNT_POINT" || true + + - name: Disconnect VPN + if: always() + run: sudo pkill -f sstpc || true diff --git a/ahk-backend/Ahk.Web.Data/ApplicationDbContext.cs b/ahk-backend/Ahk.Web.Data/ApplicationDbContext.cs index 2a89dd61..df324f8a 100644 --- a/ahk-backend/Ahk.Web.Data/ApplicationDbContext.cs +++ b/ahk-backend/Ahk.Web.Data/ApplicationDbContext.cs @@ -41,6 +41,10 @@ public ApplicationDbContext(DbContextOptions options, ICur public DbSet GradeExercisePoints => Set(); + public DbSet Assignments => Set(); + + public DbSet AssignmentAcceptances => Set(); + protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); @@ -50,6 +54,7 @@ protected override void OnModelCreating(ModelBuilder builder) e.Property(u => u.DisplayName).HasMaxLength(256); e.Property(u => u.NeptunCode).HasMaxLength(32); e.Property(u => u.Affiliation).HasMaxLength(256); + e.Property(u => u.GitHubUsername).HasMaxLength(128); // Not unique: directory accounts may have no neptun code, and it is a lookup key, not an identity. e.HasIndex(u => u.NeptunCode); @@ -181,5 +186,45 @@ protected override void OnModelCreating(ModelBuilder builder) e.Property(p => p.Name).HasMaxLength(256).IsRequired(); e.HasOne(p => p.GradeRecord).WithMany(g => g!.Points).HasForeignKey(p => p.GradeRecordId).OnDelete(DeleteBehavior.Cascade); }); + + builder.Entity(e => + { + e.Property(a => a.Name).HasMaxLength(256).IsRequired(); + e.Property(a => a.Description).HasMaxLength(1024); + e.Property(a => a.TemplateRepoName).HasMaxLength(400).IsRequired(); + e.Property(a => a.InviteToken).HasMaxLength(128).IsRequired(); + + // Globally unique: the invite link carries the token as its only identifier of the assignment, and + // it is the capability that lets a stranger provision a repository — collisions are not an option. + e.HasIndex(a => a.InviteToken).IsUnique(); + + // The instructor listing reads "this course's open assignments". + e.HasIndex(a => new { a.CourseId, a.ArchivedAt }); + + e.HasOne(a => a.Course).WithMany().HasForeignKey(a => a.CourseId).OnDelete(DeleteBehavior.Cascade); + e.HasQueryFilter(a => a.CourseId == this.currentCourse.CurrentCourseId); + }); + + builder.Entity(e => + { + e.Property(a => a.GitHubRepoName).HasMaxLength(400).IsRequired(); + e.Property(a => a.RepoUrl).HasMaxLength(1024).IsRequired(); + e.Property(a => a.GitHubUsername).HasMaxLength(128).IsRequired(); + + // One repository per student per assignment. This index is the concurrency guard: a double click or + // a second tab loses the race here rather than creating a second repository on GitHub. + e.HasIndex(a => new { a.AssignmentId, a.UserId }).IsUnique(); + e.HasIndex(a => new { a.CourseId, a.GitHubRepoName }); + + // The student home page reads every acceptance of one user across all courses. + e.HasIndex(a => a.UserId); + + // NoAction on Course: Course cascades to Assignment which cascades to here, and SQL Server rejects + // the second path. CoursesAdminController.Delete removes these rows explicitly because of it. + e.HasOne(a => a.Course).WithMany().HasForeignKey(a => a.CourseId).OnDelete(DeleteBehavior.NoAction); + e.HasOne(a => a.Assignment).WithMany(x => x!.Acceptances).HasForeignKey(a => a.AssignmentId).OnDelete(DeleteBehavior.Cascade); + e.HasOne(a => a.User).WithMany().HasForeignKey(a => a.UserId).OnDelete(DeleteBehavior.Cascade); + e.HasQueryFilter(a => a.CourseId == this.currentCourse.CurrentCourseId); + }); } } diff --git a/ahk-backend/Ahk.Web.Data/Entities/ApplicationUser.cs b/ahk-backend/Ahk.Web.Data/Entities/ApplicationUser.cs index 2b8f8b12..d1537886 100644 --- a/ahk-backend/Ahk.Web.Data/Entities/ApplicationUser.cs +++ b/ahk-backend/Ahk.Web.Data/Entities/ApplicationUser.cs @@ -23,5 +23,15 @@ public class ApplicationUser : IdentityUser /// public string? Affiliation { get; set; } + /// + /// GitHub login, verified against the GitHub API when the user first supplies it. Site-wide rather than + /// per-course: a person has one GitHub account, so once it is known no course asks for it again. + /// Copied onto when an assignment is accepted. + /// + public string? GitHubUsername { get; set; } + + /// GitHub's numeric account id — stable across a rename, which the login is not. + public long? GitHubUserId { get; set; } + public ICollection CourseMemberships { get; } = new List(); } diff --git a/ahk-backend/Ahk.Web.Data/Entities/Assignment.cs b/ahk-backend/Ahk.Web.Data/Entities/Assignment.cs new file mode 100644 index 00000000..075dbe8c --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Entities/Assignment.cs @@ -0,0 +1,46 @@ +namespace Ahk.Web.Data.Entities; + +/// +/// A piece of homework a course hands out: a template repository plus the invite link students use to get their +/// own copy of it. This is the part of the lifecycle GitHub Classroom used to own. +/// +/// Assignments are deliberately *additive*: a repository does not need one. Submissions created by external +/// tooling (or by Classroom before the migration) keep working, so nothing downstream may assume that a +/// has an assignment behind it. +/// +public class Assignment : ICourseScoped +{ + public int Id { get; set; } + + public int CourseId { get; set; } + + public Course? Course { get; set; } + + /// Shown to the student on the accept screen ("Accept the assignment — {Name}"). + public string Name { get; set; } = string.Empty; + + public string? Description { get; set; } + + /// + /// The template repository students are given a copy of, as full "owner/name", normalized with + /// . It must be marked is_template on GitHub. + /// + public string TemplateRepoName { get; set; } = string.Empty; + + /// + /// Random, unguessable segment of the invite URL (/{course}/invite/{token}). A readable slug would + /// let any signed-in user guess another course's assignment and provision themselves a repository, so the + /// link itself is the capability. Regenerating it invalidates every copy already handed out. + /// + public string InviteToken { get; set; } = string.Empty; + + /// + /// Set when the assignment is archived. Archived assignments drop out of the default listing *and* stop + /// accepting new students; those who already accepted keep their repository link. + /// + public DateTimeOffset? ArchivedAt { get; set; } + + public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; + + public ICollection Acceptances { get; } = new List(); +} diff --git a/ahk-backend/Ahk.Web.Data/Entities/AssignmentAcceptance.cs b/ahk-backend/Ahk.Web.Data/Entities/AssignmentAcceptance.cs new file mode 100644 index 00000000..ec24c64e --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Entities/AssignmentAcceptance.cs @@ -0,0 +1,52 @@ +namespace Ahk.Web.Data.Entities; + +/// +/// One student's acceptance of one : which repository was created for them and when. +/// The unique index on (AssignmentId, UserId) is what makes accepting twice — a double click, a second tab — +/// produce one repository rather than two. +/// +/// The identity link is the , not : the signed-in account is +/// who accepted, and the course-scoped student row is reachable through their Neptun code when grading needs it. +/// No submission link either — one repository can carry many submissions over a semester, and none of them are +/// this record's business. +/// +public class AssignmentAcceptance : ICourseScoped +{ + public int Id { get; set; } + + public int CourseId { get; set; } + + public Course? Course { get; set; } + + public int AssignmentId { get; set; } + + public Assignment? Assignment { get; set; } + + /// The account that clicked Accept. + public int UserId { get; set; } + + public ApplicationUser? User { get; set; } + + /// Full "owner/name" of the created repository, normalized with . + public string GitHubRepoName { get; set; } = string.Empty; + + public string RepoUrl { get; set; } = string.Empty; + + /// The GitHub login the repository was shared with, as it stood at accept time. + public string GitHubUsername { get; set; } = string.Empty; + + public DateTimeOffset AcceptedAt { get; set; } = DateTimeOffset.UtcNow; + + // --- Collaborator invitation state --- + // A student who is already an organization member is added to the repository outright (GitHub answers 204). + // Anyone else only gets an *invitation* (201) which they must accept, and which expires. Until then the + // repository is invisible to them, so the portal has to track and be able to re-send it. + + /// True while GitHub has an outstanding invitation the student has not accepted yet. + public bool InvitationPending { get; set; } + + /// GitHub's invitation id — needed to delete the stale one before issuing a replacement. + public long? InvitationId { get; set; } + + public DateTimeOffset? InvitationSentAt { get; set; } +} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260724154747_Assignments.Designer.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260724154747_Assignments.Designer.cs new file mode 100644 index 00000000..8420bf17 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Migrations/20260724154747_Assignments.Designer.cs @@ -0,0 +1,1006 @@ +// +using System; +using Ahk.Web.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Ahk.Web.Data.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20260724154747_Assignments")] + partial class Assignments + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("Affiliation") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("GitHubUserId") + .HasColumnType("bigint"); + + b.Property("GitHubUsername") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NeptunCode") + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NeptunCode"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Assignment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ArchivedAt") + .HasColumnType("datetimeoffset"); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("Description") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("InviteToken") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TemplateRepoName") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.HasKey("Id"); + + b.HasIndex("InviteToken") + .IsUnique(); + + b.HasIndex("CourseId", "ArchivedAt"); + + b.ToTable("Assignments"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.AssignmentAcceptance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AcceptedAt") + .HasColumnType("datetimeoffset"); + + b.Property("AssignmentId") + .HasColumnType("int"); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("GitHubRepoName") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("GitHubUsername") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("InvitationId") + .HasColumnType("bigint"); + + b.Property("InvitationPending") + .HasColumnType("bit"); + + b.Property("InvitationSentAt") + .HasColumnType("datetimeoffset"); + + b.Property("RepoUrl") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.HasIndex("AssignmentId", "UserId") + .IsUnique(); + + b.HasIndex("CourseId", "GitHubRepoName"); + + b.ToTable("AssignmentAcceptances"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("GitHubOrganization") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("RepoNamePrefix") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("GitHubOrganization"); + + b.HasIndex("RepoNamePrefix"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseGitHubConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("GitHubAccessToken") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("GitHubAppId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("GitHubAppPrivateKey") + .HasColumnType("nvarchar(max)"); + + b.Property("GitHubWebhookSecret") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("UpdatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("WorkflowRunThreshold") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CourseId") + .IsUnique(); + + b.ToTable("CourseGitHubConfigs"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("Role") + .HasColumnType("int"); + + b.HasKey("UserId", "CourseId"); + + b.HasIndex("CourseId"); + + b.ToTable("CourseMemberships"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseWebhookToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("Description") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("RevokedAt") + .HasColumnType("datetimeoffset"); + + b.Property("Secret") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("Token") + .IsUnique(); + + b.ToTable("CourseWebhookTokens"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeExercisePoint", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("GradeRecordId") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("Point") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("GradeRecordId"); + + b.ToTable("GradeExercisePoints"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Actor") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Confirmed") + .HasColumnType("bit"); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("Date") + .HasColumnType("datetimeoffset"); + + b.Property("Neptun") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("Origin") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("PrNumber") + .HasColumnType("int"); + + b.Property("PrUrl") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("StudentId") + .HasColumnType("int"); + + b.Property("SubmissionId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("StudentId"); + + b.HasIndex("SubmissionId"); + + b.HasIndex("CourseId", "Confirmed", "Date"); + + b.HasIndex("CourseId", "SubmissionId", "PrNumber", "Date"); + + b.ToTable("GradeRecords"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("GitHubUsername") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Neptun") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.HasKey("Id"); + + b.HasIndex("CourseId", "Neptun") + .IsUnique(); + + b.ToTable("Students"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("GitHubRepoId") + .HasColumnType("bigint"); + + b.Property("GitHubRepoName") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("LastEventAt") + .HasColumnType("datetimeoffset"); + + b.Property("StudentId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("StudentId"); + + b.HasIndex("CourseId", "GitHubRepoName") + .IsUnique(); + + b.HasIndex("CourseId", "StudentId"); + + b.ToTable("Submissions"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.SubmissionEvent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("EventType") + .IsRequired() + .HasMaxLength(34) + .HasColumnType("nvarchar(34)"); + + b.Property("GitHubDeliveryId") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SubmissionId") + .HasColumnType("int"); + + b.Property("Timestamp") + .HasColumnType("datetimeoffset"); + + b.HasKey("Id"); + + b.HasIndex("GitHubDeliveryId") + .IsUnique() + .HasFilter("[GitHubDeliveryId] IS NOT NULL"); + + b.HasIndex("SubmissionId"); + + b.HasIndex("CourseId", "SubmissionId", "Timestamp"); + + b.ToTable("SubmissionEvents"); + + b.HasDiscriminator("EventType").HasValue("SubmissionEvent"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.BranchCreatedEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.Property("Branch") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.HasDiscriminator().HasValue("BranchCreatedEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.PullRequestEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.Property("Action") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.PrimitiveCollection("Assignees") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("HtmlUrl") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("Neptun") + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("Number") + .HasColumnType("int"); + + b.HasDiscriminator().HasValue("PullRequestEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.RepositoryCreatedEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.HasDiscriminator().HasValue("RepositoryCreatedEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.WorkflowRunEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.Property("Conclusion") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasDiscriminator().HasValue("WorkflowRunEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Assignment", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.AssignmentAcceptance", b => + { + b.HasOne("Ahk.Web.Data.Entities.Assignment", "Assignment") + .WithMany("Acceptances") + .HasForeignKey("AssignmentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Assignment"); + + b.Navigation("Course"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseGitHubConfig", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithOne("GitHubConfig") + .HasForeignKey("Ahk.Web.Data.Entities.CourseGitHubConfig", "CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany("Memberships") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", "User") + .WithMany("CourseMemberships") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseWebhookToken", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeExercisePoint", b => + { + b.HasOne("Ahk.Web.Data.Entities.GradeRecord", "GradeRecord") + .WithMany("Points") + .HasForeignKey("GradeRecordId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GradeRecord"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Student", "Student") + .WithMany() + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("Ahk.Web.Data.Entities.Submission", "Submission") + .WithMany("Grades") + .HasForeignKey("SubmissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + + b.Navigation("Student"); + + b.Navigation("Submission"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Student", "Student") + .WithMany("Submissions") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("Course"); + + b.Navigation("Student"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.SubmissionEvent", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Submission", "Submission") + .WithMany("Events") + .HasForeignKey("SubmissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + + b.Navigation("Submission"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => + { + b.Navigation("CourseMemberships"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Assignment", b => + { + b.Navigation("Acceptances"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => + { + b.Navigation("GitHubConfig"); + + b.Navigation("Memberships"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => + { + b.Navigation("Points"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => + { + b.Navigation("Submissions"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => + { + b.Navigation("Events"); + + b.Navigation("Grades"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260724154747_Assignments.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260724154747_Assignments.cs new file mode 100644 index 00000000..b3970bdb --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Migrations/20260724154747_Assignments.cs @@ -0,0 +1,137 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ahk.Web.Data.Migrations +{ + /// + public partial class Assignments : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "GitHubUserId", + table: "AspNetUsers", + type: "bigint", + nullable: true); + + migrationBuilder.AddColumn( + name: "GitHubUsername", + table: "AspNetUsers", + type: "nvarchar(128)", + maxLength: 128, + nullable: true); + + migrationBuilder.CreateTable( + name: "Assignments", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + CourseId = table.Column(type: "int", nullable: false), + Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Description = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true), + TemplateRepoName = table.Column(type: "nvarchar(400)", maxLength: 400, nullable: false), + InviteToken = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + ArchivedAt = table.Column(type: "datetimeoffset", nullable: true), + CreatedAt = table.Column(type: "datetimeoffset", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Assignments", x => x.Id); + table.ForeignKey( + name: "FK_Assignments_Courses_CourseId", + column: x => x.CourseId, + principalTable: "Courses", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AssignmentAcceptances", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + CourseId = table.Column(type: "int", nullable: false), + AssignmentId = table.Column(type: "int", nullable: false), + UserId = table.Column(type: "int", nullable: false), + GitHubRepoName = table.Column(type: "nvarchar(400)", maxLength: 400, nullable: false), + RepoUrl = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: false), + GitHubUsername = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + AcceptedAt = table.Column(type: "datetimeoffset", nullable: false), + InvitationPending = table.Column(type: "bit", nullable: false), + InvitationId = table.Column(type: "bigint", nullable: true), + InvitationSentAt = table.Column(type: "datetimeoffset", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AssignmentAcceptances", x => x.Id); + table.ForeignKey( + name: "FK_AssignmentAcceptances_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AssignmentAcceptances_Assignments_AssignmentId", + column: x => x.AssignmentId, + principalTable: "Assignments", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AssignmentAcceptances_Courses_CourseId", + column: x => x.CourseId, + principalTable: "Courses", + principalColumn: "Id"); + }); + + migrationBuilder.CreateIndex( + name: "IX_AssignmentAcceptances_AssignmentId_UserId", + table: "AssignmentAcceptances", + columns: new[] { "AssignmentId", "UserId" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_AssignmentAcceptances_CourseId_GitHubRepoName", + table: "AssignmentAcceptances", + columns: new[] { "CourseId", "GitHubRepoName" }); + + migrationBuilder.CreateIndex( + name: "IX_AssignmentAcceptances_UserId", + table: "AssignmentAcceptances", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_Assignments_CourseId_ArchivedAt", + table: "Assignments", + columns: new[] { "CourseId", "ArchivedAt" }); + + migrationBuilder.CreateIndex( + name: "IX_Assignments_InviteToken", + table: "Assignments", + column: "InviteToken", + unique: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AssignmentAcceptances"); + + migrationBuilder.DropTable( + name: "Assignments"); + + migrationBuilder.DropColumn( + name: "GitHubUserId", + table: "AspNetUsers"); + + migrationBuilder.DropColumn( + name: "GitHubUsername", + table: "AspNetUsers"); + } + } +} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/ApplicationDbContextModelSnapshot.cs b/ahk-backend/Ahk.Web.Data/Migrations/ApplicationDbContextModelSnapshot.cs index 52915996..49c0f5de 100644 --- a/ahk-backend/Ahk.Web.Data/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/ahk-backend/Ahk.Web.Data/Migrations/ApplicationDbContextModelSnapshot.cs @@ -82,6 +82,13 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("EmailConfirmed") .HasColumnType("bit"); + b.Property("GitHubUserId") + .HasColumnType("bigint"); + + b.Property("GitHubUsername") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + b.Property("LockoutEnabled") .HasColumnType("bit"); @@ -134,6 +141,108 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("AspNetUsers", (string)null); }); + modelBuilder.Entity("Ahk.Web.Data.Entities.Assignment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ArchivedAt") + .HasColumnType("datetimeoffset"); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("Description") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("InviteToken") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TemplateRepoName") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.HasKey("Id"); + + b.HasIndex("InviteToken") + .IsUnique(); + + b.HasIndex("CourseId", "ArchivedAt"); + + b.ToTable("Assignments"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.AssignmentAcceptance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AcceptedAt") + .HasColumnType("datetimeoffset"); + + b.Property("AssignmentId") + .HasColumnType("int"); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("GitHubRepoName") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("GitHubUsername") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("InvitationId") + .HasColumnType("bigint"); + + b.Property("InvitationPending") + .HasColumnType("bit"); + + b.Property("InvitationSentAt") + .HasColumnType("datetimeoffset"); + + b.Property("RepoUrl") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.HasIndex("AssignmentId", "UserId") + .IsUnique(); + + b.HasIndex("CourseId", "GitHubRepoName"); + + b.ToTable("AssignmentAcceptances"); + }); + modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => { b.Property("Id") @@ -640,6 +749,44 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasDiscriminator().HasValue("WorkflowRunEvent"); }); + modelBuilder.Entity("Ahk.Web.Data.Entities.Assignment", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.AssignmentAcceptance", b => + { + b.HasOne("Ahk.Web.Data.Entities.Assignment", "Assignment") + .WithMany("Acceptances") + .HasForeignKey("AssignmentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Assignment"); + + b.Navigation("Course"); + + b.Navigation("User"); + }); + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseGitHubConfig", b => { b.HasOne("Ahk.Web.Data.Entities.Course", "Course") @@ -822,6 +969,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("CourseMemberships"); }); + modelBuilder.Entity("Ahk.Web.Data.Entities.Assignment", b => + { + b.Navigation("Acceptances"); + }); + modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => { b.Navigation("GitHubConfig"); diff --git a/ahk-backend/Ahk.Web.Data/Seed/DevDataSeeder.cs b/ahk-backend/Ahk.Web.Data/Seed/DevDataSeeder.cs index 506f8437..58a79a0c 100644 --- a/ahk-backend/Ahk.Web.Data/Seed/DevDataSeeder.cs +++ b/ahk-backend/Ahk.Web.Data/Seed/DevDataSeeder.cs @@ -65,6 +65,38 @@ public static async Task SeedAsync(IServiceProvider services) } await EnsureSampleDomainDataAsync(db, courseA); + await EnsureSampleAssignmentsAsync(db, courseA); + } + + /// + /// One open and one archived assignment, so the instructor listing, the "show archived" toggle and the + /// closed-invite branch all have something to render. + /// + private static async Task EnsureSampleAssignmentsAsync(ApplicationDbContext db, Course course) + { + if (await db.Assignments.IgnoreQueryFilters().AnyAsync(a => a.CourseId == course.Id)) + return; + + db.Assignments.AddRange( + new Assignment + { + CourseId = course.Id, + Name = "Homework 1 — Data access", + Description = "Implement the repository layer and open a pull request from the solution branch.", + TemplateRepoName = Normalize.RepoName($"{course.GitHubOrganization}/{course.Slug}-hw1"), + InviteToken = $"dev-invite-{course.Slug}-hw1", + }, + new Assignment + { + CourseId = course.Id, + Name = "Homework 0 — Warm-up (archived)", + Description = "Last semester's warm-up assignment. Archived: the invite link no longer accepts students.", + TemplateRepoName = Normalize.RepoName($"{course.GitHubOrganization}/{course.Slug}-hw0"), + InviteToken = $"dev-invite-{course.Slug}-hw0", + ArchivedAt = DateTimeOffset.UtcNow.AddDays(-30), + }); + + await db.SaveChangesAsync(); } private static async Task EnsureCourseAsync(ApplicationDbContext db, string slug, string name, string org, string? webhookSecret) diff --git a/ahk-backend/Ahk.Web.Data/TokenGenerator.cs b/ahk-backend/Ahk.Web.Data/TokenGenerator.cs new file mode 100644 index 00000000..13c4d374 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/TokenGenerator.cs @@ -0,0 +1,17 @@ +using System.Security.Cryptography; + +namespace Ahk.Web.Data; + +/// +/// Random identifiers that travel in URLs and HTTP headers: CI callback tokens and assignment invite links. +/// Base64 with the two URL-hostile characters swapped and the padding dropped, so the value can be pasted +/// anywhere without escaping. +/// +public static class TokenGenerator +{ + public static string UrlSafe(int byteLength) => + Convert.ToBase64String(RandomNumberGenerator.GetBytes(byteLength)) + .Replace('+', '-') + .Replace('/', '_') + .TrimEnd('='); +} diff --git a/ahk-backend/Ahk.Web.Server.Tests/ApiSmokeTests.cs b/ahk-backend/Ahk.Web.Server.Tests/ApiSmokeTests.cs index f73a42f0..7156a33d 100644 --- a/ahk-backend/Ahk.Web.Server.Tests/ApiSmokeTests.cs +++ b/ahk-backend/Ahk.Web.Server.Tests/ApiSmokeTests.cs @@ -1,6 +1,7 @@ using System.Linq; using System.Net; using Ahk.Web.Data; +using Ahk.Web.Data.Entities; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc.Testing; @@ -83,6 +84,30 @@ public async Task UnknownCourseSlug_Returns404_BeforeAuth() Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } + /// + /// The student-facing surfaces need a session, but nothing more. They are reachable by people who are not + /// members of any course — that is the point of an invite link — so they must sit behind plain + /// authentication rather than the CourseMember policy. + /// + [Theory] + [InlineData("/api/my/assignments")] + [InlineData("/api/viaubc01/invite/some-token")] + public async Task StudentEndpoints_WithoutAuth_Return401(string url) + { + var client = factory.CreateClient(); + var response = await client.GetAsync(url); + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); + } + + /// Assignment administration stays behind course membership, unlike the invite endpoint. + [Fact] + public async Task AssignmentAdministration_WithoutAuth_Returns401() + { + var client = factory.CreateClient(); + var response = await client.GetAsync("/api/viaubc01/assignments"); + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); + } + public sealed class TestAppFactory : WebApplicationFactory { protected override IHost CreateHost(IHostBuilder builder) @@ -105,7 +130,22 @@ protected override IHost CreateHost(IHostBuilder builder) services.AddDbContext(options => options.UseInMemoryDatabase("ApiSmokeTests")); }); - return base.CreateHost(builder); + var host = base.CreateHost(builder); + + // CourseResolutionMiddleware 404s an unknown {course} slug before authorization ever runs, so the + // course-scoped tests need a real course to aim at — otherwise they would assert 404 and prove + // nothing about the policy on the endpoint. + using (var scope = host.Services.CreateScope()) + { + var db = scope.ServiceProvider.GetRequiredService(); + if (!db.Courses.Any(c => c.Slug == "viaubc01")) + { + db.Courses.Add(new Course { Slug = "viaubc01", Name = "Sample Course" }); + db.SaveChanges(); + } + } + + return host; } } } diff --git a/ahk-backend/Ahk.Web.Server.Tests/AssignmentInviteTests.cs b/ahk-backend/Ahk.Web.Server.Tests/AssignmentInviteTests.cs new file mode 100644 index 00000000..0753f45d --- /dev/null +++ b/ahk-backend/Ahk.Web.Server.Tests/AssignmentInviteTests.cs @@ -0,0 +1,300 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Ahk.Web.Services.Assignments; +using Ahk.Web.Services.GitHub; +using Ahk.Web.Services.Submissions; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging.Abstractions; +using Moq; +using Xunit; + +namespace Ahk.Web.Server.Tests; + +/// +/// The invite state machine, against a mocked GitHub. This is the path a student walks unattended, so each +/// branch is pinned: what is still missing, what happens when the repository is already there, and that +/// accepting twice does not produce two repositories. +/// +public class AssignmentInviteTests +{ + private const int CourseId = 1; + private const string InviteToken = "invite-token"; + + private sealed class FixedCourseProvider : ICurrentCourseProvider + { + public int? CurrentCourseId => CourseId; + } + + private sealed class Fixture : IAsyncDisposable + { + public Fixture(bool archived = false, string? organization = "ahk-org") + { + var options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .Options; + + Db = new ApplicationDbContext(options, new FixedCourseProvider()); + + Db.Courses.Add(new Course { Id = CourseId, Slug = "viaubc01", Name = "Sample Course", GitHubOrganization = organization }); + Db.Assignments.Add(new Assignment + { + Id = 10, + CourseId = CourseId, + Name = "Homework 1", + TemplateRepoName = "ahk-org/viaubc01-hw1", + InviteToken = InviteToken, + ArchivedAt = archived ? DateTimeOffset.UtcNow.AddDays(-1) : null, + }); + Db.SaveChanges(); + + GitHub = new Mock(MockBehavior.Strict); + Tokens = new Mock(); + Tokens + .Setup(t => t.GetForCourseAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync(new GitHubInstallationToken("gh-token", 42, new Dictionary { ["administration"] = "write" }, "all")); + + Service = new AssignmentInviteService( + Db, + GitHub.Object, + Tokens.Object, + new SubmissionResolver(Db), + NullLogger.Instance); + } + + public ApplicationDbContext Db { get; } + + public Mock GitHub { get; } + + public Mock Tokens { get; } + + public AssignmentInviteService Service { get; } + + /// A student who has everything the flow needs, unless a field is nulled out by the caller. + public ApplicationUser AddUser(string? neptun = "ABC123", string? gitHubUsername = "octocat") + { + var user = new ApplicationUser { Id = 7, UserName = "student@bme.hu", NeptunCode = neptun, GitHubUsername = gitHubUsername }; + Db.Users.Add(user); + Db.SaveChanges(); + return user; + } + + /// Wires the mock for the happy path: the repository does not exist yet and gets created. + public void ExpectRepositoryCreated(bool invitationCreated = false) + { + GitHub + .Setup(g => g.GetRepositoryAsync("ahk-org", "viaubc01-hw1-abc123", "gh-token", It.IsAny())) + .ReturnsAsync((GitHubRepository?)null); + + GitHub + .Setup(g => g.GenerateFromTemplateAsync("ahk-org", "viaubc01-hw1", "ahk-org", "viaubc01-hw1-abc123", "gh-token", It.IsAny())) + .ReturnsAsync(new GitHubRepository("ahk-org/viaubc01-hw1-abc123", "https://github.com/ahk-org/viaubc01-hw1-abc123", false, "main")); + + GitHub + .Setup(g => g.EnsureActionsEnabledAsync("ahk-org", "viaubc01-hw1-abc123", "gh-token", It.IsAny())) + .Returns(Task.CompletedTask); + + GitHub + .Setup(g => g.AddCollaboratorAsync("ahk-org", "viaubc01-hw1-abc123", "octocat", "gh-token", It.IsAny())) + .ReturnsAsync(new CollaboratorResult(invitationCreated, invitationCreated ? 99 : null)); + } + + public ValueTask DisposeAsync() => Db.DisposeAsync(); + } + + [Fact] + public async Task WithoutNeptunCode_TheFlowStopsAndExplainsWhy() + { + await using var fixture = new Fixture(); + var user = fixture.AddUser(neptun: null); + + var state = await fixture.Service.GetStateAsync(CourseId, InviteToken, user); + + Assert.Equal(InviteStatus.NeedsNeptun, state.Status); + Assert.Contains("eduID", state.Message, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public async Task WithoutGitHubUsername_TheStudentIsAskedForOne() + { + await using var fixture = new Fixture(); + var user = fixture.AddUser(gitHubUsername: null); + + var state = await fixture.Service.GetStateAsync(CourseId, InviteToken, user); + + Assert.Equal(InviteStatus.NeedsGitHubUsername, state.Status); + + // The repository name is already known, so the screen can tell them what they are about to get. + Assert.Equal("viaubc01-hw1-abc123", state.RepositoryName); + } + + [Fact] + public async Task WithEverythingInPlace_TheStudentIsAskedToConfirm() + { + await using var fixture = new Fixture(); + var user = fixture.AddUser(); + + var state = await fixture.Service.GetStateAsync(CourseId, InviteToken, user); + + Assert.Equal(InviteStatus.ReadyToAccept, state.Status); + Assert.Equal("ahk-org", state.Organization); + Assert.Equal("viaubc01-hw1-abc123", state.RepositoryName); + } + + [Fact] + public async Task AnArchivedAssignment_TurnsNewStudentsAway() + { + await using var fixture = new Fixture(archived: true); + var user = fixture.AddUser(); + + var state = await fixture.Service.GetStateAsync(CourseId, InviteToken, user); + + Assert.Equal(InviteStatus.Closed, state.Status); + } + + /// Archiving closes the door to newcomers; it does not take a repository away from someone who has one. + [Fact] + public async Task AnArchivedAssignment_StillShowsTheRepositoryToStudentsWhoAccepted() + { + await using var fixture = new Fixture(archived: true); + var user = fixture.AddUser(); + + fixture.Db.AssignmentAcceptances.Add(new AssignmentAcceptance + { + CourseId = CourseId, + AssignmentId = 10, + UserId = user.Id, + GitHubRepoName = "ahk-org/viaubc01-hw1-abc123", + RepoUrl = "https://github.com/ahk-org/viaubc01-hw1-abc123", + GitHubUsername = "octocat", + }); + await fixture.Db.SaveChangesAsync(); + + var state = await fixture.Service.GetStateAsync(CourseId, InviteToken, user); + + Assert.Equal(InviteStatus.Accepted, state.Status); + Assert.Equal("https://github.com/ahk-org/viaubc01-hw1-abc123", state.RepoUrl); + } + + [Fact] + public async Task AnUnknownToken_IsNotFound() + { + await using var fixture = new Fixture(); + var user = fixture.AddUser(); + + var state = await fixture.Service.GetStateAsync(CourseId, "no-such-token", user); + + Assert.Equal(InviteStatus.NotFound, state.Status); + } + + [Fact] + public async Task Accepting_CreatesTheRepository_GrantsAccess_AndRecordsThePair() + { + await using var fixture = new Fixture(); + var user = fixture.AddUser(); + fixture.ExpectRepositoryCreated(); + + var state = await fixture.Service.AcceptAsync(CourseId, InviteToken, user); + + Assert.Equal(InviteStatus.Accepted, state.Status); + Assert.Equal("https://github.com/ahk-org/viaubc01-hw1-abc123", state.RepoUrl); + + fixture.GitHub.Verify( + g => g.GenerateFromTemplateAsync("ahk-org", "viaubc01-hw1", "ahk-org", "viaubc01-hw1-abc123", "gh-token", It.IsAny()), + Times.Once); + fixture.GitHub.Verify( + g => g.AddCollaboratorAsync("ahk-org", "viaubc01-hw1-abc123", "octocat", "gh-token", It.IsAny()), + Times.Once); + + var acceptance = Assert.Single(await fixture.Db.AssignmentAcceptances.IgnoreQueryFilters().ToListAsync()); + Assert.Equal("ahk-org/viaubc01-hw1-abc123", acceptance.GitHubRepoName); + Assert.False(acceptance.InvitationPending); + + // The student is enrolled and the submission exists, so grades and events have somewhere to land before + // the first webhook ever arrives. + Assert.Single(await fixture.Db.Students.IgnoreQueryFilters().Where(s => s.Neptun == "ABC123").ToListAsync()); + Assert.Single(await fixture.Db.Submissions.IgnoreQueryFilters().Where(s => s.GitHubRepoName == "ahk-org/viaubc01-hw1-abc123").ToListAsync()); + } + + /// A student outside the organization is only invited, and the invitation has to be tracked. + [Fact] + public async Task Accepting_RecordsAPendingInvitationWhenGitHubOnlyInvites() + { + await using var fixture = new Fixture(); + var user = fixture.AddUser(); + fixture.ExpectRepositoryCreated(invitationCreated: true); + + var state = await fixture.Service.AcceptAsync(CourseId, InviteToken, user); + + Assert.Equal(InviteStatus.Accepted, state.Status); + Assert.Equal("https://github.com/ahk-org/viaubc01-hw1-abc123/invitations", state.InvitationUrl); + + var acceptance = Assert.Single(await fixture.Db.AssignmentAcceptances.IgnoreQueryFilters().ToListAsync()); + Assert.True(acceptance.InvitationPending); + Assert.Equal(99, acceptance.InvitationId); + Assert.NotNull(acceptance.InvitationSentAt); + } + + /// + /// The repository may already exist — a re-run, a manual creation, a migrated course. Linking it is right; + /// creating a second one is not, and GitHub would reject it anyway. + /// + [Fact] + public async Task Accepting_LinksAnExistingRepositoryInsteadOfCreatingASecondOne() + { + await using var fixture = new Fixture(); + var user = fixture.AddUser(); + + fixture.GitHub + .Setup(g => g.GetRepositoryAsync("ahk-org", "viaubc01-hw1-abc123", "gh-token", It.IsAny())) + .ReturnsAsync(new GitHubRepository("ahk-org/viaubc01-hw1-abc123", "https://github.com/ahk-org/viaubc01-hw1-abc123", false, "main")); + + fixture.GitHub + .Setup(g => g.AddCollaboratorAsync("ahk-org", "viaubc01-hw1-abc123", "octocat", "gh-token", It.IsAny())) + .ReturnsAsync(new CollaboratorResult(false, null)); + + var state = await fixture.Service.AcceptAsync(CourseId, InviteToken, user); + + Assert.Equal(InviteStatus.Accepted, state.Status); + fixture.GitHub.Verify( + g => g.GenerateFromTemplateAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), + Times.Never); + } + + /// Reloading the page, or clicking Accept twice, must not hand out a second repository. + [Fact] + public async Task AcceptingTwice_ReturnsTheSameRepositoryAndTouchesGitHubOnce() + { + await using var fixture = new Fixture(); + var user = fixture.AddUser(); + fixture.ExpectRepositoryCreated(); + + await fixture.Service.AcceptAsync(CourseId, InviteToken, user); + var second = await fixture.Service.AcceptAsync(CourseId, InviteToken, user); + + Assert.Equal(InviteStatus.Accepted, second.Status); + Assert.Single(await fixture.Db.AssignmentAcceptances.IgnoreQueryFilters().ToListAsync()); + + fixture.GitHub.Verify( + g => g.GenerateFromTemplateAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), + Times.Once); + } + + /// A course with no organization cannot create anything; say so rather than failing at GitHub. + [Fact] + public async Task ACourseWithoutAnOrganization_ReportsItIsNotConfigured() + { + await using var fixture = new Fixture(organization: null); + var user = fixture.AddUser(); + + var state = await fixture.Service.GetStateAsync(CourseId, InviteToken, user); + + Assert.Equal(InviteStatus.NotConfigured, state.Status); + } + + [Theory] + [InlineData("ahk-org/viaubc01-hw1", "ABC123", "viaubc01-hw1-abc123")] + [InlineData("org/hw", "xyz789", "hw-xyz789")] + [InlineData("no-owner", "ABC123", "no-owner-abc123")] + public void RepositoryName_IsTheTemplateNamePlusNeptun_Lowercased(string template, string neptun, string expected) => + Assert.Equal(expected, AssignmentInviteService.BuildRepositoryName(template, neptun)); +} diff --git a/ahk-backend/Ahk.Web.Server.Tests/AssignmentScopingTests.cs b/ahk-backend/Ahk.Web.Server.Tests/AssignmentScopingTests.cs new file mode 100644 index 00000000..73ce06ee --- /dev/null +++ b/ahk-backend/Ahk.Web.Server.Tests/AssignmentScopingTests.cs @@ -0,0 +1,109 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Microsoft.EntityFrameworkCore; +using Xunit; + +namespace Ahk.Web.Server.Tests; + +/// +/// The course query filter must cover the assignment entities too. Assignments carry an invite link that +/// provisions repositories, so one course seeing another's would be worse than a data leak — it would let a +/// student of course A accept course B's homework. +/// +public class AssignmentScopingTests +{ + private const int CourseA = 1; + private const int CourseB = 2; + + private sealed class MutableCourseProvider : ICurrentCourseProvider + { + public int? CurrentCourseId { get; set; } + } + + private static ApplicationDbContext CreateContext(ICurrentCourseProvider provider, string dbName) + { + var options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(dbName) + .Options; + return new ApplicationDbContext(options, provider); + } + + private static async Task SeedTwoCoursesAsync(string dbName) + { + await using var db = CreateContext(new MutableCourseProvider { CurrentCourseId = null }, dbName); + + foreach (var (courseId, slug) in new[] { (CourseA, "a"), (CourseB, "b") }) + { + var user = new ApplicationUser { Id = courseId + 100, UserName = $"student-{slug}", NeptunCode = "ABC123" }; + db.Users.Add(user); + + var assignment = new Assignment + { + CourseId = courseId, + Name = $"Homework of {slug}", + TemplateRepoName = $"org/{slug}-hw1", + InviteToken = $"token-{slug}", + }; + db.Assignments.Add(assignment); + await db.SaveChangesAsync(); + + db.AssignmentAcceptances.Add(new AssignmentAcceptance + { + CourseId = courseId, + AssignmentId = assignment.Id, + UserId = user.Id, + GitHubRepoName = $"org/{slug}-hw1-abc123", + RepoUrl = $"https://github.com/org/{slug}-hw1-abc123", + GitHubUsername = "octocat", + }); + await db.SaveChangesAsync(); + } + } + + [Theory] + [InlineData(CourseA, "org/a-hw1")] + [InlineData(CourseB, "org/b-hw1")] + public async Task Assignments_AreFilteredToTheCurrentCourse(int courseId, string expectedTemplate) + { + var dbName = Guid.NewGuid().ToString(); + await SeedTwoCoursesAsync(dbName); + + await using var db = CreateContext(new MutableCourseProvider { CurrentCourseId = courseId }, dbName); + + var assignments = await db.Assignments.ToListAsync(); + Assert.Single(assignments); + Assert.Equal(expectedTemplate, assignments[0].TemplateRepoName); + } + + [Fact] + public async Task Acceptances_AreFilteredToTheCurrentCourse() + { + var dbName = Guid.NewGuid().ToString(); + await SeedTwoCoursesAsync(dbName); + + await using var db = CreateContext(new MutableCourseProvider { CurrentCourseId = CourseA }, dbName); + + var acceptances = await db.AssignmentAcceptances.ToListAsync(); + Assert.Single(acceptances); + Assert.Equal(CourseA, acceptances[0].CourseId); + } + + /// + /// The student home page and the invite service run without a {course} route segment, so they see nothing + /// unless they bypass the filter. This pins that trap in place rather than leaving it to be rediscovered. + /// + [Fact] + public async Task NoCurrentCourse_HidesAssignmentsUnlessFiltersAreIgnored() + { + var dbName = Guid.NewGuid().ToString(); + await SeedTwoCoursesAsync(dbName); + + await using var db = CreateContext(new MutableCourseProvider { CurrentCourseId = null }, dbName); + + Assert.Empty(await db.Assignments.ToListAsync()); + Assert.Empty(await db.AssignmentAcceptances.ToListAsync()); + + Assert.Equal(2, await db.Assignments.IgnoreQueryFilters().CountAsync()); + Assert.Equal(2, await db.AssignmentAcceptances.IgnoreQueryFilters().CountAsync()); + } +} diff --git a/ahk-backend/Ahk.Web.Server.Tests/StudentAssignmentTests.cs b/ahk-backend/Ahk.Web.Server.Tests/StudentAssignmentTests.cs new file mode 100644 index 00000000..d3597f0c --- /dev/null +++ b/ahk-backend/Ahk.Web.Server.Tests/StudentAssignmentTests.cs @@ -0,0 +1,210 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Ahk.Web.Services.Assignments; +using Ahk.Web.Services.GitHub; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging.Abstractions; +using Moq; +using Xunit; + +namespace Ahk.Web.Server.Tests; + +/// +/// The student's home page. Its whole job is to answer "can I actually open this repository yet", which means +/// reconciling what the database remembers with what GitHub currently says — a pending invitation may have been +/// accepted, or may have quietly expired. +/// +public class StudentAssignmentTests +{ + private const int CourseId = 1; + private const int UserId = 7; + + /// + /// Null current course, deliberately: these endpoints carry no {course} segment. If the service ever stops + /// using IgnoreQueryFilters, these tests go from green to empty results. + /// + private sealed class NoCourseProvider : ICurrentCourseProvider + { + public int? CurrentCourseId => null; + } + + private sealed class Fixture : IAsyncDisposable + { + public Fixture(bool invitationPending, long? invitationId) + { + var options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(Guid.NewGuid().ToString()) + .Options; + + Db = new ApplicationDbContext(options, new NoCourseProvider()); + + Db.Courses.Add(new Course { Id = CourseId, Slug = "viaubc01", Name = "Sample Course", GitHubOrganization = "ahk-org" }); + Db.Users.Add(new ApplicationUser { Id = UserId, UserName = "student@bme.hu" }); + Db.Assignments.Add(new Assignment { Id = 10, CourseId = CourseId, Name = "Homework 1", TemplateRepoName = "ahk-org/viaubc01-hw1", InviteToken = "t" }); + Db.AssignmentAcceptances.Add(new AssignmentAcceptance + { + Id = 100, + CourseId = CourseId, + AssignmentId = 10, + UserId = UserId, + GitHubRepoName = "ahk-org/viaubc01-hw1-abc123", + RepoUrl = "https://github.com/ahk-org/viaubc01-hw1-abc123", + GitHubUsername = "octocat", + InvitationPending = invitationPending, + InvitationId = invitationId, + InvitationSentAt = invitationPending ? DateTimeOffset.UtcNow.AddDays(-8) : null, + }); + Db.SaveChanges(); + + GitHub = new Mock(); + Tokens = new Mock(); + Tokens + .Setup(t => t.GetForCourseAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync(new GitHubInstallationToken("gh-token", 42, new Dictionary(), "all")); + + Service = new StudentAssignmentService(Db, GitHub.Object, Tokens.Object, NullLogger.Instance); + } + + public ApplicationDbContext Db { get; } + + public Mock GitHub { get; } + + public Mock Tokens { get; } + + public StudentAssignmentService Service { get; } + + public ValueTask DisposeAsync() => Db.DisposeAsync(); + } + + [Fact] + public async Task ASettledRepository_IsListedAsActiveWithoutAskingGitHub() + { + await using var fixture = new Fixture(invitationPending: false, invitationId: null); + + var repositories = await fixture.Service.ListForUserAsync(UserId); + + var repository = Assert.Single(repositories); + Assert.Equal(RepositoryAccess.Active, repository.Access); + Assert.Equal("viaubc01", repository.CourseSlug); + Assert.Equal("Homework 1", repository.AssignmentName); + Assert.Null(repository.InvitationUrl); + + fixture.GitHub.Verify( + g => g.IsCollaboratorAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), + Times.Never); + } + + /// The student accepted the invitation on GitHub; the portal should notice and stop nagging them. + [Fact] + public async Task AnInvitationAcceptedOnGitHub_IsClearedAndReportedAsActive() + { + await using var fixture = new Fixture(invitationPending: true, invitationId: 99); + + fixture.GitHub + .Setup(g => g.IsCollaboratorAsync("ahk-org", "viaubc01-hw1-abc123", "octocat", "gh-token", It.IsAny())) + .ReturnsAsync(true); + + var repositories = await fixture.Service.ListForUserAsync(UserId); + + Assert.Equal(RepositoryAccess.Active, Assert.Single(repositories).Access); + + var stored = await fixture.Db.AssignmentAcceptances.IgnoreQueryFilters().SingleAsync(); + Assert.False(stored.InvitationPending); + Assert.Null(stored.InvitationId); + } + + /// No access and no invitation left on GitHub means it lapsed — offer the resend, do not leave them waiting. + [Fact] + public async Task AnInvitationGitHubNoLongerHas_IsReportedAsExpired() + { + await using var fixture = new Fixture(invitationPending: true, invitationId: 99); + + fixture.GitHub + .Setup(g => g.IsCollaboratorAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync(false); + fixture.GitHub + .Setup(g => g.FindInvitationAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync((GitHubInvitation?)null); + + var repositories = await fixture.Service.ListForUserAsync(UserId); + + Assert.Equal(RepositoryAccess.InvitationExpired, Assert.Single(repositories).Access); + } + + [Fact] + public async Task AnInvitationStillWaiting_IsReportedAsPendingWithSomewhereToGo() + { + await using var fixture = new Fixture(invitationPending: true, invitationId: 99); + + fixture.GitHub + .Setup(g => g.IsCollaboratorAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync(false); + fixture.GitHub + .Setup(g => g.FindInvitationAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync(new GitHubInvitation(99, "octocat", Expired: false, DateTimeOffset.UtcNow.AddDays(-1))); + + var repository = Assert.Single(await fixture.Service.ListForUserAsync(UserId)); + + Assert.Equal(RepositoryAccess.InvitationPending, repository.Access); + Assert.Equal("https://github.com/ahk-org/viaubc01-hw1-abc123/invitations", repository.InvitationUrl); + } + + /// GitHub cannot extend an invitation, so the stale one has to be withdrawn before a new one is sent. + [Fact] + public async Task Resending_WithdrawsTheStaleInvitationAndStoresTheNewOne() + { + await using var fixture = new Fixture(invitationPending: true, invitationId: 99); + + fixture.GitHub + .Setup(g => g.IsCollaboratorAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync(false); + fixture.GitHub + .Setup(g => g.FindInvitationAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync(new GitHubInvitation(99, "octocat", Expired: true, DateTimeOffset.UtcNow.AddDays(-8))); + fixture.GitHub + .Setup(g => g.DeleteInvitationAsync("ahk-org", "viaubc01-hw1-abc123", 99, "gh-token", It.IsAny())) + .Returns(Task.CompletedTask); + fixture.GitHub + .Setup(g => g.AddCollaboratorAsync("ahk-org", "viaubc01-hw1-abc123", "octocat", "gh-token", It.IsAny())) + .ReturnsAsync(new CollaboratorResult(true, 123)); + + var result = await fixture.Service.ResendInvitationAsync(UserId, 100); + + Assert.NotNull(result); + Assert.Equal(RepositoryAccess.InvitationPending, result!.Access); + + fixture.GitHub.Verify(g => g.DeleteInvitationAsync("ahk-org", "viaubc01-hw1-abc123", 99, "gh-token", It.IsAny()), Times.Once); + + var stored = await fixture.Db.AssignmentAcceptances.IgnoreQueryFilters().SingleAsync(); + Assert.Equal(123, stored.InvitationId); + Assert.True(stored.InvitationPending); + } + + /// They accepted between drawing the page and clicking Resend; do not send a pointless invitation. + [Fact] + public async Task Resending_DoesNothingWhenTheStudentAlreadyHasAccess() + { + await using var fixture = new Fixture(invitationPending: true, invitationId: 99); + + fixture.GitHub + .Setup(g => g.IsCollaboratorAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync(true); + + var result = await fixture.Service.ResendInvitationAsync(UserId, 100); + + Assert.Equal(RepositoryAccess.Active, result!.Access); + fixture.GitHub.Verify( + g => g.AddCollaboratorAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), + Times.Never); + } + + /// An acceptance belonging to someone else is not found, not someone else's repository. + [Fact] + public async Task Resending_AnotherStudentsAcceptance_IsRefused() + { + await using var fixture = new Fixture(invitationPending: true, invitationId: 99); + + Assert.Null(await fixture.Service.ResendInvitationAsync(userId: 999, acceptanceId: 100)); + Assert.Empty(await fixture.Service.ListForUserAsync(999)); + } +} diff --git a/ahk-backend/Ahk.Web.Server/Admin/CoursesAdminController.cs b/ahk-backend/Ahk.Web.Server/Admin/CoursesAdminController.cs index 7638e71c..b5798aed 100644 --- a/ahk-backend/Ahk.Web.Server/Admin/CoursesAdminController.cs +++ b/ahk-backend/Ahk.Web.Server/Admin/CoursesAdminController.cs @@ -178,13 +178,15 @@ public async Task Delete(int id, [FromQuery] string? confirmSlug, if (!string.Equals(course.Slug, confirmSlug, StringComparison.Ordinal)) return BadRequest(new { error = $"Type the course slug '{course.Slug}' to confirm deletion." }); - // GradeRecord and SubmissionEvent point at Course with NoAction (SQL Server rejects the extra cascade - // paths), so they are removed explicitly before the course goes. + // GradeRecord, SubmissionEvent and AssignmentAcceptance point at Course with NoAction (SQL Server + // rejects the extra cascade paths), so they are removed explicitly before the course goes. await db.GradeExercisePoints.IgnoreQueryFilters() .Where(p => p.GradeRecord!.CourseId == id).ExecuteDeleteAsync(cancellationToken); await db.GradeRecords.IgnoreQueryFilters().Where(g => g.CourseId == id).ExecuteDeleteAsync(cancellationToken); await db.SubmissionEvents.IgnoreQueryFilters().Where(e => e.CourseId == id).ExecuteDeleteAsync(cancellationToken); await db.Submissions.IgnoreQueryFilters().Where(s => s.CourseId == id).ExecuteDeleteAsync(cancellationToken); + await db.AssignmentAcceptances.IgnoreQueryFilters().Where(a => a.CourseId == id).ExecuteDeleteAsync(cancellationToken); + await db.Assignments.IgnoreQueryFilters().Where(a => a.CourseId == id).ExecuteDeleteAsync(cancellationToken); db.Courses.Remove(course); await db.SaveChangesAsync(cancellationToken); diff --git a/ahk-backend/Ahk.Web.Server/Auth/AuthController.cs b/ahk-backend/Ahk.Web.Server/Auth/AuthController.cs index f28b7911..8e12ed6d 100644 --- a/ahk-backend/Ahk.Web.Server/Auth/AuthController.cs +++ b/ahk-backend/Ahk.Web.Server/Auth/AuthController.cs @@ -167,6 +167,8 @@ private async Task BuildCurrentUserAsync(ApplicationUser us UserName = user.UserName ?? string.Empty, Email = user.Email, DisplayName = user.DisplayName, + NeptunCode = user.NeptunCode, + GitHubUsername = user.GitHubUsername, Roles = roles.ToList(), Courses = courses, }; diff --git a/ahk-backend/Ahk.Web.Server/Auth/Dto/CurrentUserResponse.cs b/ahk-backend/Ahk.Web.Server/Auth/Dto/CurrentUserResponse.cs index 092d9f82..ee73e738 100644 --- a/ahk-backend/Ahk.Web.Server/Auth/Dto/CurrentUserResponse.cs +++ b/ahk-backend/Ahk.Web.Server/Auth/Dto/CurrentUserResponse.cs @@ -11,6 +11,15 @@ public sealed class CurrentUserResponse public string? DisplayName { get; set; } + /// + /// From the IdP's neptun_code claim. The invite flow needs it to name a student's repository, and + /// the SPA needs to know whether it is there before offering to accept an assignment. + /// + public string? NeptunCode { get; set; } + + /// Verified GitHub login, or null while the user has not supplied one. + public string? GitHubUsername { get; set; } + public IReadOnlyList Roles { get; set; } = Array.Empty(); /// diff --git a/ahk-backend/Ahk.Web.Server/Auth/ProfileController.cs b/ahk-backend/Ahk.Web.Server/Auth/ProfileController.cs new file mode 100644 index 00000000..e8e189af --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Auth/ProfileController.cs @@ -0,0 +1,117 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Ahk.Web.Services.GitHub; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace Ahk.Web.Server.Auth; + +public sealed class SetGitHubUsernameRequest +{ + public string GitHubUsername { get; set; } = string.Empty; + + /// + /// Optional course whose GitHub App token pays for the lookup. Purely a rate-limit matter — the call works + /// unauthenticated too, at 60 requests an hour instead of 5000. The invite page always has a course to name. + /// + public string? CourseSlug { get; set; } +} + +public sealed class GitHubProfileResponse +{ + public string GitHubUsername { get; set; } = string.Empty; + + public long? GitHubUserId { get; set; } +} + +/// +/// The parts of a user's own profile they maintain themselves. Today that is one thing: their GitHub account, +/// which the portal needs before it can hand them a repository. +/// +[ApiController] +[Route("api/profile")] +[Authorize] +public sealed class ProfileController : ControllerBase +{ + private readonly UserManager userManager; + private readonly IGitHubRepositoryService gitHub; + private readonly ICourseGitHubAppTokenProvider tokens; + private readonly ApplicationDbContext db; + + public ProfileController( + UserManager userManager, + IGitHubRepositoryService gitHub, + ICourseGitHubAppTokenProvider tokens, + ApplicationDbContext db) + { + this.userManager = userManager; + this.gitHub = gitHub; + this.tokens = tokens; + this.db = db; + } + + /// + /// Records the caller's GitHub login, after checking it exists. The check is GET /users/{login} + /// rather than a fetch of the profile page: a 404 there is unambiguous, and the response carries the + /// numeric account id, which survives the user renaming themselves later. + /// + [HttpPut("github")] + [ProducesResponseType(typeof(GitHubProfileResponse), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status502BadGateway)] + public async Task> SetGitHubUsername([FromBody] SetGitHubUsernameRequest request, CancellationToken cancellationToken) + { + ArgumentNullException.ThrowIfNull(request); + + var user = await userManager.GetUserAsync(User); + if (user is null) + return Unauthorized(); + + // A pasted profile URL is the obvious mistake to be forgiving about; everything else must be a login. + var login = request.GitHubUsername?.Trim().TrimEnd('/') ?? string.Empty; + var lastSlash = login.LastIndexOf('/'); + if (lastSlash >= 0) + login = login[(lastSlash + 1)..]; + + if (string.IsNullOrWhiteSpace(login)) + return BadRequest(new { error = "Enter your GitHub username." }); + + string? token = null; + if (!string.IsNullOrWhiteSpace(request.CourseSlug)) + { + var courseId = await db.Courses.AsNoTracking() + .Where(c => c.Slug == request.CourseSlug) + .Select(c => c.Id) + .FirstOrDefaultAsync(cancellationToken); + + if (courseId != 0) + token = (await tokens.GetForCourseAsync(courseId, bypassCache: false, cancellationToken))?.Token; + } + + GitHubUser? account; + try + { + account = await gitHub.GetUserAsync(login, token, cancellationToken); + } + catch (Exception ex) when (ex is GitHubOperationException or HttpRequestException or TaskCanceledException) + { + return StatusCode(StatusCodes.Status502BadGateway, new { error = "GitHub could not be reached to check that username. Try again in a few minutes." }); + } + + if (account is null) + return BadRequest(new { error = $"There is no GitHub user called \"{login}\". Check the spelling — it is the name in your profile URL, github.com/." }); + + // Store GitHub's own casing, so the value shown back matches the account exactly. + user.GitHubUsername = account.Login; + user.GitHubUserId = account.Id; + + var result = await userManager.UpdateAsync(user); + if (!result.Succeeded) + return BadRequest(new { errors = result.Errors.Select(e => e.Description) }); + + return Ok(new GitHubProfileResponse { GitHubUsername = account.Login, GitHubUserId = account.Id }); + } +} diff --git a/ahk-backend/Ahk.Web.Server/Courses/AssignmentInviteController.cs b/ahk-backend/Ahk.Web.Server/Courses/AssignmentInviteController.cs new file mode 100644 index 00000000..ad8e9f84 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Courses/AssignmentInviteController.cs @@ -0,0 +1,97 @@ +using Ahk.Web.Data.Entities; +using Ahk.Web.Server.CourseContext; +using Ahk.Web.Services.Assignments; +using Ahk.Web.Services.GitHub; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; + +namespace Ahk.Web.Server.Courses; + +/// +/// The student side of an assignment: follow the invite link, confirm, get a repository. Replaces GitHub +/// Classroom's accept flow. +/// +/// ⚠️ [Authorize] without the CourseMember policy, deliberately. Students are not members of the +/// course — accepting is how they first appear in it at all — so requiring membership here would lock every +/// student out of the one endpoint meant for them. still resolves the +/// {course} segment, so the course query filter behaves normally; the invite token is the capability that +/// authorizes the request. +/// +[ApiController] +[Route("api/{course}/invite/{token}")] +[Authorize] +public sealed class AssignmentInviteController : ControllerBase +{ + private readonly IAssignmentInviteService invites; + private readonly UserManager userManager; + private readonly ILogger logger; + + public AssignmentInviteController( + IAssignmentInviteService invites, + UserManager userManager, + ILogger logger) + { + this.invites = invites; + this.userManager = userManager; + this.logger = logger; + } + + /// Where this student stands: what is still missing, or the repository they already have. + [HttpGet] + [ProducesResponseType(typeof(InviteState), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + public async Task> Get(string token, CancellationToken cancellationToken) + { + var user = await userManager.GetUserAsync(User); + if (user is null) + return Unauthorized(); + + var course = CurrentCourse(); + return Ok(await invites.GetStateAsync(course.Id, token, user, cancellationToken)); + } + + /// + /// Creates the student's repository and grants them access. Idempotent: accepting twice returns the same + /// repository rather than creating a second one. + /// + [HttpPost("accept")] + [ProducesResponseType(typeof(InviteState), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status502BadGateway)] + public async Task> Accept(string token, CancellationToken cancellationToken) + { + var user = await userManager.GetUserAsync(User); + if (user is null) + return Unauthorized(); + + var course = CurrentCourse(); + + try + { + return Ok(await invites.AcceptAsync(course.Id, token, user, cancellationToken)); + } + catch (GitHubOperationException ex) + { + // GitHub refused something we asked for. Its own words are far more useful to the instructor who + // will be asked about it than "an error occurred". + logger.LogError(ex, "Accepting invite {Token} in course {Course} failed at GitHub.", token, course.Slug); + + return StatusCode(StatusCodes.Status502BadGateway, new + { + error = $"GitHub refused to set up the repository: {ex.GitHubMessage ?? ex.Message} Tell your instructor — this is a configuration problem, not something you did.", + }); + } + catch (HttpRequestException ex) + { + logger.LogError(ex, "Accepting invite {Token} in course {Course} could not reach GitHub.", token, course.Slug); + + return StatusCode(StatusCodes.Status502BadGateway, new + { + error = "GitHub could not be reached. Try again in a few minutes.", + }); + } + } + + private Course CurrentCourse() => (Course)HttpContext.Items[CourseResolutionMiddleware.CourseItemKey]!; +} diff --git a/ahk-backend/Ahk.Web.Server/Courses/AssignmentsController.cs b/ahk-backend/Ahk.Web.Server/Courses/AssignmentsController.cs new file mode 100644 index 00000000..c69dbeb2 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Courses/AssignmentsController.cs @@ -0,0 +1,208 @@ +using Ahk.Web.Data.Entities; +using Ahk.Web.Server.Courses.Dto; +using Ahk.Web.Server.CourseContext; +using Ahk.Web.Services.Assignments; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace Ahk.Web.Server.Courses; + +/// +/// Course-scoped assignment administration: what used to be set up in GitHub Classroom. Staff define an +/// assignment against a template repository and hand out its invite link; students provision themselves through +/// . +/// +/// Assignments are additive. Repositories created outside the portal keep working exactly as before, so nothing +/// here is a precondition for grading or status tracking. +/// +[ApiController] +[Route("api/{course}/assignments")] +[Authorize(Policy = CourseMembershipRequirement.PolicyName)] +public sealed class AssignmentsController : ControllerBase +{ + private readonly IAssignmentService assignments; + + public AssignmentsController(IAssignmentService assignments) => this.assignments = assignments; + + [HttpGet] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + public async Task>> List([FromQuery] bool includeArchived, CancellationToken cancellationToken) + { + var course = CurrentCourse(); + var items = await assignments.ListAsync(course.Id, includeArchived, cancellationToken); + var counts = await assignments.CountAcceptancesAsync(course.Id, cancellationToken); + + return Ok(items.Select(a => ToDto(a, course, counts.GetValueOrDefault(a.Id))).ToList()); + } + + /// + /// One assignment. additionally asks GitHub whether the template + /// repository exists and is marked as a template — a network call, so the editor opts into it rather than + /// every listing paying for it. + /// + [HttpGet("{id:int}")] + [ProducesResponseType(typeof(AssignmentDetailDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> Get(int id, [FromQuery] bool checkTemplate, CancellationToken cancellationToken) + { + var course = CurrentCourse(); + var assignment = await assignments.GetAsync(course.Id, id, cancellationToken); + if (assignment is null) + return NotFound(); + + var acceptances = await assignments.ListAcceptancesAsync(course.Id, id, cancellationToken); + + return Ok(new AssignmentDetailDto + { + Assignment = ToDto(assignment, course, acceptances.Count), + Template = checkTemplate + ? TemplateCheckDto.From(await assignments.CheckTemplateAsync(course.Id, assignment.TemplateRepoName, cancellationToken)) + : null, + }); + } + + [HttpPost] + [ProducesResponseType(typeof(AssignmentDto), StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public async Task> Create([FromBody] SaveAssignmentRequest request, CancellationToken cancellationToken) + { + ArgumentNullException.ThrowIfNull(request); + + if (Validate(request) is { } error) + return BadRequest(new { error }); + + var course = CurrentCourse(); + var assignment = await assignments.CreateAsync(course.Id, ToInput(request), cancellationToken); + + return CreatedAtAction(nameof(Get), new { course = course.Slug, id = assignment.Id }, ToDto(assignment, course, 0)); + } + + [HttpPut("{id:int}")] + [ProducesResponseType(typeof(AssignmentDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> Update(int id, [FromBody] SaveAssignmentRequest request, CancellationToken cancellationToken) + { + ArgumentNullException.ThrowIfNull(request); + + if (Validate(request) is { } error) + return BadRequest(new { error }); + + var course = CurrentCourse(); + var assignment = await assignments.UpdateAsync(course.Id, id, ToInput(request), cancellationToken); + + return assignment is null ? NotFound() : Ok(ToDto(assignment, course, 0)); + } + + [HttpPost("{id:int}/archive")] + [ProducesResponseType(typeof(AssignmentDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public Task> Archive(int id, CancellationToken cancellationToken) => + SetArchivedAsync(id, archived: true, cancellationToken); + + [HttpPost("{id:int}/unarchive")] + [ProducesResponseType(typeof(AssignmentDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public Task> Unarchive(int id, CancellationToken cancellationToken) => + SetArchivedAsync(id, archived: false, cancellationToken); + + /// Issues a new invite link. Every copy of the previous one stops working immediately. + [HttpPost("{id:int}/regenerate-invite")] + [ProducesResponseType(typeof(AssignmentDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> RegenerateInvite(int id, CancellationToken cancellationToken) + { + var course = CurrentCourse(); + var assignment = await assignments.RegenerateInviteTokenAsync(course.Id, id, cancellationToken); + + return assignment is null ? NotFound() : Ok(ToDto(assignment, course, 0)); + } + + /// + /// Deletes an assignment nobody has accepted. Once students hold repositories the record is the only trace + /// of who got what, so the API refuses and points at archiving instead. + /// + [HttpDelete("{id:int}")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(StatusCodes.Status409Conflict)] + public async Task Delete(int id, CancellationToken cancellationToken) + { + var course = CurrentCourse(); + + var assignment = await assignments.GetAsync(course.Id, id, cancellationToken); + if (assignment is null) + return NotFound(); + + if (!await assignments.DeleteAsync(course.Id, id, cancellationToken)) + { + return Conflict(new + { + error = "Students have already accepted this assignment, so it cannot be deleted. Archive it instead — that closes the invite link and keeps their repositories linked.", + }); + } + + return NoContent(); + } + + [HttpGet("{id:int}/acceptances")] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + public async Task>> ListAcceptances(int id, CancellationToken cancellationToken) + { + var course = CurrentCourse(); + var acceptances = await assignments.ListAcceptancesAsync(course.Id, id, cancellationToken); + + return Ok(acceptances.Select(a => new AssignmentAcceptanceDto + { + Id = a.Id, + UserName = a.User?.UserName ?? string.Empty, + DisplayName = a.User?.DisplayName, + NeptunCode = a.User?.NeptunCode, + GitHubUsername = a.GitHubUsername, + GitHubRepoName = a.GitHubRepoName, + RepoUrl = a.RepoUrl, + AcceptedAt = a.AcceptedAt, + InvitationPending = a.InvitationPending, + }).ToList()); + } + + private async Task> SetArchivedAsync(int id, bool archived, CancellationToken cancellationToken) + { + var course = CurrentCourse(); + var assignment = await assignments.SetArchivedAsync(course.Id, id, archived, cancellationToken); + + return assignment is null ? NotFound() : Ok(ToDto(assignment, course, 0)); + } + + private static string? Validate(SaveAssignmentRequest request) + { + if (string.IsNullOrWhiteSpace(request.Name)) + return "An assignment needs a name."; + + return string.IsNullOrWhiteSpace(request.TemplateRepoName) + ? "An assignment needs a template repository." + : null; + } + + private static AssignmentInput ToInput(SaveAssignmentRequest request) => new() + { + Name = request.Name, + Description = request.Description, + TemplateRepoName = request.TemplateRepoName, + }; + + private AssignmentDto ToDto(Assignment assignment, Course course, int acceptanceCount) => new() + { + Id = assignment.Id, + Name = assignment.Name, + Description = assignment.Description, + TemplateRepoName = assignment.TemplateRepoName, + InvitePath = $"/{course.Slug}/invite/{assignment.InviteToken}", + IsArchived = assignment.ArchivedAt is not null, + ArchivedAt = assignment.ArchivedAt, + CreatedAt = assignment.CreatedAt, + AcceptanceCount = acceptanceCount, + }; + + private Course CurrentCourse() => (Course)HttpContext.Items[CourseResolutionMiddleware.CourseItemKey]!; +} diff --git a/ahk-backend/Ahk.Web.Server/Courses/Dto/AssignmentDto.cs b/ahk-backend/Ahk.Web.Server/Courses/Dto/AssignmentDto.cs new file mode 100644 index 00000000..e8ee2fb4 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Courses/Dto/AssignmentDto.cs @@ -0,0 +1,101 @@ +using Ahk.Web.Services.Assignments; + +namespace Ahk.Web.Server.Courses.Dto; + +/// An assignment as the instructor screens see it. +public sealed class AssignmentDto +{ + public int Id { get; set; } + + public string Name { get; set; } = string.Empty; + + public string? Description { get; set; } + + /// Full "owner/name" of the template repository students are given a copy of. + public string TemplateRepoName { get; set; } = string.Empty; + + /// + /// The invite link as a site-relative path (/{course}/invite/{token}). Deliberately not an absolute + /// URL: the API would have to build one from the Host header, and the Angular dev proxy rewrites that to + /// the backend's own port — producing a link that works for nobody. The browser knows the origin the + /// student will actually use, so it composes the final URL. + /// + public string InvitePath { get; set; } = string.Empty; + + public bool IsArchived { get; set; } + + public DateTimeOffset? ArchivedAt { get; set; } + + public DateTimeOffset CreatedAt { get; set; } + + /// How many students have taken this assignment up. + public int AcceptanceCount { get; set; } +} + +/// An assignment plus the state of its template repository on GitHub. +public sealed class AssignmentDetailDto +{ + public AssignmentDto Assignment { get; set; } = new(); + + /// Null when the template was not checked (the check costs a GitHub call, so it is opt-in). + public TemplateCheckDto? Template { get; set; } +} + +/// Advisory result of looking the template repository up on GitHub. +public sealed class TemplateCheckDto +{ + public bool Reachable { get; set; } + + public bool IsTemplate { get; set; } + + public string? HtmlUrl { get; set; } + + /// What is wrong, in one sentence; null when the template is fine. + public string? Problem { get; set; } + + public static TemplateCheckDto From(TemplateCheck check) + { + ArgumentNullException.ThrowIfNull(check); + + return new TemplateCheckDto + { + Reachable = check.Reachable, + IsTemplate = check.IsTemplate, + HtmlUrl = check.HtmlUrl, + Problem = check.Problem, + }; + } +} + +public sealed class SaveAssignmentRequest +{ + public string Name { get; set; } = string.Empty; + + public string? Description { get; set; } + + /// "owner/name", or a bare repository name taken to be in the course's organization. + public string TemplateRepoName { get; set; } = string.Empty; +} + +/// One student's acceptance, as the instructor's roster of an assignment shows it. +public sealed class AssignmentAcceptanceDto +{ + public int Id { get; set; } + + public string UserName { get; set; } = string.Empty; + + public string? DisplayName { get; set; } + + public string? NeptunCode { get; set; } + + public string GitHubUsername { get; set; } = string.Empty; + + public string GitHubRepoName { get; set; } = string.Empty; + + public string RepoUrl { get; set; } = string.Empty; + + public DateTimeOffset AcceptedAt { get; set; } + + /// True while the student has been invited to their repository but has not accepted yet. + public bool InvitationPending { get; set; } +} diff --git a/ahk-backend/Ahk.Web.Server/Program.cs b/ahk-backend/Ahk.Web.Server/Program.cs index 7faf9860..9f1ac92f 100644 --- a/ahk-backend/Ahk.Web.Server/Program.cs +++ b/ahk-backend/Ahk.Web.Server/Program.cs @@ -244,6 +244,11 @@ private static async Task ConfigurePipelineAsync(WebApplication app) app.UseHttpsRedirection(); + // Serve the Angular SPA (published into wwwroot). Same-origin with the API, so the generated + // clients' empty API_BASE_URL keeps issuing relative /api/... requests. Must run before routing. + app.UseDefaultFiles(); + app.UseStaticFiles(); + app.UseRouting(); app.UseAuthentication(); app.UseMiddleware(); @@ -254,5 +259,9 @@ private static async Task ConfigurePipelineAsync(WebApplication app) app.MapMockOidcProvider(); app.MapControllers(); + + // Client-side routes (e.g. /admin/courses) have no server endpoint; hand them index.html and let + // the Angular router take over. Matched controller/static routes win first, so /api/... is untouched. + app.MapFallbackToFile("index.html"); } } diff --git a/ahk-backend/Ahk.Web.Server/Properties/PublishProfiles/Mezga.pubxml b/ahk-backend/Ahk.Web.Server/Properties/PublishProfiles/Mezga.pubxml new file mode 100644 index 00000000..4f338d3e --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Properties/PublishProfiles/Mezga.pubxml @@ -0,0 +1,22 @@ + + + + + FileSystem + FileSystem + Release + Any CPU + Release + Any CPU + true + net10.0 + win-x64 + true + <_IsPortable>true + bin\Release\net10.0\publish\ + + diff --git a/ahk-backend/Ahk.Web.Server/Students/MyAssignmentsController.cs b/ahk-backend/Ahk.Web.Server/Students/MyAssignmentsController.cs new file mode 100644 index 00000000..80759ef3 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Students/MyAssignmentsController.cs @@ -0,0 +1,83 @@ +using Ahk.Web.Data.Entities; +using Ahk.Web.Services.Assignments; +using Ahk.Web.Services.GitHub; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; + +namespace Ahk.Web.Server.Students; + +/// +/// A student's own view: every repository they hold, across every course, and a way to re-send a GitHub +/// invitation that lapsed before they clicked it. +/// +/// No {course} segment — a student's repositories span courses, and they are members of none of them. The +/// service behind this filters on the user id with IgnoreQueryFilters() for exactly that reason. +/// +[ApiController] +[Route("api/my/assignments")] +[Authorize] +public sealed class MyAssignmentsController : ControllerBase +{ + private readonly IStudentAssignmentService studentAssignments; + private readonly UserManager userManager; + private readonly ILogger logger; + + public MyAssignmentsController( + IStudentAssignmentService studentAssignments, + UserManager userManager, + ILogger logger) + { + this.studentAssignments = studentAssignments; + this.userManager = userManager; + this.logger = logger; + } + + [HttpGet] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + public async Task>> List(CancellationToken cancellationToken) + { + var user = await userManager.GetUserAsync(User); + if (user is null) + return Unauthorized(); + + return Ok(await studentAssignments.ListForUserAsync(user.Id, cancellationToken)); + } + + /// + /// Withdraws the stale invitation and issues a fresh one. GitHub has no way to extend an invitation, so + /// replacing it is the only route back in for a student who missed the window. + /// + [HttpPost("{id:int}/resend-invitation")] + [ProducesResponseType(typeof(StudentRepository), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [ProducesResponseType(StatusCodes.Status502BadGateway)] + public async Task> ResendInvitation(int id, CancellationToken cancellationToken) + { + var user = await userManager.GetUserAsync(User); + if (user is null) + return Unauthorized(); + + try + { + // Scoped to the caller's own acceptances, so another student's id is a 404, not someone else's repo. + var result = await studentAssignments.ResendInvitationAsync(user.Id, id, cancellationToken); + return result is null ? NotFound() : Ok(result); + } + catch (GitHubOperationException ex) + { + logger.LogError(ex, "Re-sending the invitation for acceptance {AcceptanceId} failed at GitHub.", id); + + return StatusCode(StatusCodes.Status502BadGateway, new + { + error = $"GitHub refused to send the invitation: {ex.GitHubMessage ?? ex.Message}", + }); + } + catch (HttpRequestException) + { + return StatusCode(StatusCodes.Status502BadGateway, new { error = "GitHub could not be reached. Try again in a few minutes." }); + } + } +} diff --git a/ahk-backend/Ahk.Web.Server/app_offline.htm b/ahk-backend/Ahk.Web.Server/app_offline.htm new file mode 100644 index 00000000..4ee628ef --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/app_offline.htm @@ -0,0 +1,41 @@ + + + + + + + AHK — deployment in progress + + + +
+

Deployment in progress

+

The AHK portal is being updated and will be back in a few moments.

+

Please refresh this page shortly.

+
+ + diff --git a/ahk-backend/Ahk.Web.Services/Assignments/AssignmentInviteService.cs b/ahk-backend/Ahk.Web.Services/Assignments/AssignmentInviteService.cs new file mode 100644 index 00000000..e75a0a00 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/Assignments/AssignmentInviteService.cs @@ -0,0 +1,319 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Ahk.Web.Services.GitHub; +using Ahk.Web.Services.Submissions; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; + +namespace Ahk.Web.Services.Assignments; + +/// Where a student stands on one assignment's invite link. +public enum InviteStatus +{ + /// No assignment answers to that invite token in this course — a stale or mistyped link. + NotFound, + + /// Archived, and this student never accepted it. No new repositories are handed out. + Closed, + + /// The account carries no Neptun code, so no repository can be named for it. Terminal. + NeedsNeptun, + + /// The account has no verified GitHub login yet. + NeedsGitHubUsername, + + /// Everything is in place; the student only has to confirm. + ReadyToAccept, + + /// The repository exists and is theirs. + Accepted, + + /// The course is not wired up to GitHub, so nothing can be created. Terminal, and the instructor's problem. + NotConfigured, +} + +/// Everything the invite screen renders, in one shape for both the read and the accept call. +public sealed class InviteState +{ + public InviteStatus Status { get; set; } + + public string CourseName { get; set; } = string.Empty; + + public string CourseSlug { get; set; } = string.Empty; + + public string AssignmentName { get; set; } = string.Empty; + + public string? AssignmentDescription { get; set; } + + /// The GitHub organization the repository lives in, named in the confirmation text. + public string? Organization { get; set; } + + /// The repository the student is about to get, or already has, without the owner prefix. + public string? RepositoryName { get; set; } + + public string? RepoUrl { get; set; } + + public string? GitHubUsername { get; set; } + + /// + /// Set when GitHub only *invited* the student rather than adding them. Until they accept it there, the + /// repository 404s for them, so the UI must send them here instead of to the repository. + /// + public string? InvitationUrl { get; set; } + + /// Human-readable detail for the terminal states; null when there is nothing extra to say. + public string? Message { get; set; } +} + +public interface IAssignmentInviteService +{ + Task GetStateAsync(int courseId, string inviteToken, ApplicationUser user, CancellationToken cancellationToken = default); + + Task AcceptAsync(int courseId, string inviteToken, ApplicationUser user, CancellationToken cancellationToken = default); +} + +/// +/// Drives a student from an invite link to a repository of their own: verify who they are, create the +/// repository from the assignment's template, give them push access, and record the pair. This is the part of +/// GitHub Classroom the portal takes over. +/// +/// Everything it does is idempotent. A student who reloads, double-clicks, or opens the link in two tabs ends +/// up with exactly one repository — guarded by the unique index on (AssignmentId, UserId) and by checking +/// GitHub for the repository before creating it. +/// +public sealed class AssignmentInviteService : IAssignmentInviteService +{ + private readonly ApplicationDbContext db; + private readonly IGitHubRepositoryService gitHub; + private readonly ICourseGitHubAppTokenProvider tokens; + private readonly ISubmissionResolver submissions; + private readonly ILogger logger; + + public AssignmentInviteService( + ApplicationDbContext db, + IGitHubRepositoryService gitHub, + ICourseGitHubAppTokenProvider tokens, + ISubmissionResolver submissions, + ILogger logger) + { + this.db = db; + this.gitHub = gitHub; + this.tokens = tokens; + this.submissions = submissions; + this.logger = logger; + } + + public async Task GetStateAsync(int courseId, string inviteToken, ApplicationUser user, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(user); + + var context = await LoadAsync(courseId, inviteToken, cancellationToken); + if (context is null) + return new InviteState { Status = InviteStatus.NotFound, Message = "This invite link does not match an assignment. Ask your instructor for a current one." }; + + var (course, assignment) = context.Value; + var acceptance = await FindAcceptanceAsync(assignment.Id, user.Id, cancellationToken); + + var state = Describe(course, assignment, user, acceptance); + + // An accepted student keeps their link forever; only newcomers are turned away by archiving. + if (acceptance is not null) + return state; + + if (assignment.ArchivedAt is not null) + { + state.Status = InviteStatus.Closed; + state.Message = "This assignment is no longer accepting new repositories."; + return state; + } + + return state; + } + + public async Task AcceptAsync(int courseId, string inviteToken, ApplicationUser user, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(user); + + // The client is not trusted: everything GetStateAsync decided is decided again here. + var state = await GetStateAsync(courseId, inviteToken, user, cancellationToken); + if (state.Status != InviteStatus.ReadyToAccept) + return state; + + var context = await LoadAsync(courseId, inviteToken, cancellationToken); + if (context is null) + return new InviteState { Status = InviteStatus.NotFound }; + + var (course, assignment) = context.Value; + + var token = await tokens.GetForCourseAsync(course, bypassCache: false, cancellationToken); + if (token is null) + return NotConfigured(state); + + // Enrolls the student in the course on first contact — the model has no roster import, here or anywhere. + var student = await submissions.GetOrCreateStudentAsync(courseId, user.NeptunCode!, cancellationToken); + if (!string.Equals(student.GitHubUsername, user.GitHubUsername, StringComparison.OrdinalIgnoreCase)) + { + student.GitHubUsername = user.GitHubUsername; + await db.SaveChangesAsync(cancellationToken); + } + + var organization = course.GitHubOrganization!; + var repositoryName = BuildRepositoryName(assignment.TemplateRepoName, student.Neptun); + var fullName = Normalize.RepoName($"{organization}/{repositoryName}"); + + var existing = await gitHub.GetRepositoryAsync(organization, repositoryName, token.Token, cancellationToken); + var repository = existing; + + if (repository is null) + { + var (templateOwner, templateName) = IAssignmentService.SplitRepoName(assignment.TemplateRepoName); + + repository = await gitHub.GenerateFromTemplateAsync( + templateOwner, templateName, organization, repositoryName, token.Token, cancellationToken); + + // Belt and braces. A generated repository normally has Actions on, but the evaluator is the whole + // point of the repository, so it is worth one call not to find out otherwise weeks later. + try + { + await gitHub.EnsureActionsEnabledAsync(organization, repositoryName, token.Token, cancellationToken); + } + catch (GitHubOperationException ex) + { + logger.LogWarning(ex, "Could not enable Actions on {Repository}; the repository was still created.", fullName); + } + } + + var collaborator = await gitHub.AddCollaboratorAsync(organization, repositoryName, user.GitHubUsername!, token.Token, cancellationToken); + + // Created eagerly so grades and status events land on the right row even before the first webhook. + // No SubmissionEvent is written here: the webhook receiver owns the event log, and a second + // "repository created" would double-count in the status projection. + await submissions.GetOrCreateAsync(courseId, fullName, student.Neptun, cancellationToken); + + var acceptance = new AssignmentAcceptance + { + CourseId = courseId, + AssignmentId = assignment.Id, + UserId = user.Id, + GitHubRepoName = fullName, + RepoUrl = repository.HtmlUrl, + GitHubUsername = user.GitHubUsername!, + InvitationPending = collaborator.InvitationCreated, + InvitationId = collaborator.InvitationId, + InvitationSentAt = collaborator.InvitationCreated ? DateTimeOffset.UtcNow : null, + }; + + db.AssignmentAcceptances.Add(acceptance); + + try + { + await db.SaveChangesAsync(cancellationToken); + } + catch (DbUpdateException) + { + // Lost the race against another tab. The unique index did its job; report the row that won. + db.Entry(acceptance).State = EntityState.Detached; + + var winner = await FindAcceptanceAsync(assignment.Id, user.Id, cancellationToken); + if (winner is null) + throw; + + acceptance = winner; + } + + var result = Describe(course, assignment, user, acceptance); + if (existing is not null) + result.Message = "This repository already existed, so it was linked to you rather than created again."; + + return result; + } + + /// + /// The student's repository name: the template repository's own name with their Neptun code appended, the + /// convention the courses already use. Lowercased like every repository name in the model. + /// + internal static string BuildRepositoryName(string templateRepoName, string neptun) + { + var (_, name) = IAssignmentService.SplitRepoName(templateRepoName); + return Normalize.RepoName($"{name}-{neptun}"); + } + + private InviteState Describe(Course course, Assignment assignment, ApplicationUser user, AssignmentAcceptance? acceptance) + { + var state = new InviteState + { + CourseName = course.Name, + CourseSlug = course.Slug, + AssignmentName = assignment.Name, + AssignmentDescription = assignment.Description, + Organization = course.GitHubOrganization, + GitHubUsername = user.GitHubUsername, + }; + + if (acceptance is not null) + { + var (owner, name) = IAssignmentService.SplitRepoName(acceptance.GitHubRepoName); + + state.Status = InviteStatus.Accepted; + state.RepositoryName = name; + state.RepoUrl = acceptance.RepoUrl; + state.GitHubUsername = acceptance.GitHubUsername; + state.InvitationUrl = acceptance.InvitationPending ? $"https://github.com/{owner}/{name}/invitations" : null; + return state; + } + + if (string.IsNullOrWhiteSpace(course.GitHubOrganization)) + { + state.Status = InviteStatus.NotConfigured; + state.Message = "This course is not connected to a GitHub organization yet. Ask your instructor to finish setting it up."; + return state; + } + + if (string.IsNullOrWhiteSpace(user.NeptunCode)) + { + state.Status = InviteStatus.NeedsNeptun; + state.Message = "This account has no Neptun code, so no repository can be created for it. Sign in with your BME eduID account instead."; + return state; + } + + state.RepositoryName = BuildRepositoryName(assignment.TemplateRepoName, Normalize.Neptun(user.NeptunCode)); + + if (string.IsNullOrWhiteSpace(user.GitHubUsername)) + { + state.Status = InviteStatus.NeedsGitHubUsername; + return state; + } + + state.Status = InviteStatus.ReadyToAccept; + return state; + } + + private static InviteState NotConfigured(InviteState state) + { + state.Status = InviteStatus.NotConfigured; + state.Message = "This course has no working GitHub App configured, so repositories cannot be created. Ask your instructor to check it."; + return state; + } + + private async Task<(Course Course, Assignment Assignment)?> LoadAsync(int courseId, string inviteToken, CancellationToken cancellationToken) + { + if (string.IsNullOrWhiteSpace(inviteToken)) + return null; + + var assignment = await db.Assignments.IgnoreQueryFilters().AsNoTracking() + .FirstOrDefaultAsync(a => a.CourseId == courseId && a.InviteToken == inviteToken, cancellationToken); + + if (assignment is null) + return null; + + var course = await db.Courses.AsNoTracking() + .Include(c => c.GitHubConfig) + .FirstOrDefaultAsync(c => c.Id == courseId, cancellationToken); + + return course is null ? null : (course, assignment); + } + + private async Task FindAcceptanceAsync(int assignmentId, int userId, CancellationToken cancellationToken) => + await db.AssignmentAcceptances.IgnoreQueryFilters().AsNoTracking() + .FirstOrDefaultAsync(a => a.AssignmentId == assignmentId && a.UserId == userId, cancellationToken); +} diff --git a/ahk-backend/Ahk.Web.Services/Assignments/AssignmentService.cs b/ahk-backend/Ahk.Web.Services/Assignments/AssignmentService.cs new file mode 100644 index 00000000..a1966a7f --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/Assignments/AssignmentService.cs @@ -0,0 +1,252 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Ahk.Web.Services.GitHub; +using Microsoft.EntityFrameworkCore; + +namespace Ahk.Web.Services.Assignments; + +/// What an instructor supplies when creating or editing an assignment. +public sealed class AssignmentInput +{ + public string Name { get; set; } = string.Empty; + + public string? Description { get; set; } + + /// Either "owner/name" or a bare repository name, which is taken to be in the course's organization. + public string TemplateRepoName { get; set; } = string.Empty; +} + +/// +/// The result of checking an assignment's template repository on GitHub. Advisory: an assignment may be drafted +/// before its template exists, so a problem here is reported, never enforced. +/// +public sealed record TemplateCheck(bool Reachable, bool IsTemplate, string? HtmlUrl, string? Problem); + +public interface IAssignmentService +{ + Task> ListAsync(int courseId, bool includeArchived, CancellationToken cancellationToken = default); + + Task GetAsync(int courseId, int assignmentId, CancellationToken cancellationToken = default); + + Task CreateAsync(int courseId, AssignmentInput input, CancellationToken cancellationToken = default); + + Task UpdateAsync(int courseId, int assignmentId, AssignmentInput input, CancellationToken cancellationToken = default); + + /// Archives or restores. Archiving also closes the invite link to students who have not accepted yet. + Task SetArchivedAsync(int courseId, int assignmentId, bool archived, CancellationToken cancellationToken = default); + + /// Issues a fresh invite token, which invalidates every copy of the old link. + Task RegenerateInviteTokenAsync(int courseId, int assignmentId, CancellationToken cancellationToken = default); + + /// Deletes an assignment. Refuses once students have accepted it — archive those instead. + Task DeleteAsync(int courseId, int assignmentId, CancellationToken cancellationToken = default); + + Task> ListAcceptancesAsync(int courseId, int assignmentId, CancellationToken cancellationToken = default); + + /// Acceptances per assignment for a whole course, so the listing needs one query rather than one per row. + Task> CountAcceptancesAsync(int courseId, CancellationToken cancellationToken = default); + + /// Verifies the template repository exists and is marked as a template. Never throws. + Task CheckTemplateAsync(int courseId, string templateRepoName, CancellationToken cancellationToken = default); + + /// Splits a stored "owner/name" into its parts. + static (string Owner, string Name) SplitRepoName(string fullName) + { + ArgumentNullException.ThrowIfNull(fullName); + + var separator = fullName.IndexOf('/', StringComparison.Ordinal); + return separator < 0 + ? (string.Empty, fullName) + : (fullName[..separator], fullName[(separator + 1)..]); + } +} + +/// +/// Assignment administration for instructors. Like every other service here it takes an explicit +/// courseId and reads with IgnoreQueryFilters(): the ambient course filter follows +/// , which is only set on requests that carry a {course} route segment. +/// +public sealed class AssignmentService : IAssignmentService +{ + private readonly ApplicationDbContext db; + private readonly IGitHubRepositoryService gitHub; + private readonly ICourseGitHubAppTokenProvider tokens; + + public AssignmentService(ApplicationDbContext db, IGitHubRepositoryService gitHub, ICourseGitHubAppTokenProvider tokens) + { + this.db = db; + this.gitHub = gitHub; + this.tokens = tokens; + } + + public async Task> ListAsync(int courseId, bool includeArchived, CancellationToken cancellationToken = default) + { + var query = db.Assignments.IgnoreQueryFilters().AsNoTracking().Where(a => a.CourseId == courseId); + + if (!includeArchived) + query = query.Where(a => a.ArchivedAt == null); + + return await query + .OrderBy(a => a.ArchivedAt == null ? 0 : 1) + .ThenByDescending(a => a.CreatedAt) + .ToListAsync(cancellationToken); + } + + public async Task GetAsync(int courseId, int assignmentId, CancellationToken cancellationToken = default) => + await db.Assignments.IgnoreQueryFilters().AsNoTracking() + .FirstOrDefaultAsync(a => a.Id == assignmentId && a.CourseId == courseId, cancellationToken); + + public async Task CreateAsync(int courseId, AssignmentInput input, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(input); + + var assignment = new Assignment + { + CourseId = courseId, + Name = input.Name.Trim(), + Description = Trimmed(input.Description), + TemplateRepoName = await QualifyRepoNameAsync(courseId, input.TemplateRepoName, cancellationToken), + InviteToken = TokenGenerator.UrlSafe(18), + }; + + db.Assignments.Add(assignment); + await db.SaveChangesAsync(cancellationToken); + return assignment; + } + + public async Task UpdateAsync(int courseId, int assignmentId, AssignmentInput input, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(input); + + var assignment = await TrackedAsync(courseId, assignmentId, cancellationToken); + if (assignment is null) + return null; + + assignment.Name = input.Name.Trim(); + assignment.Description = Trimmed(input.Description); + assignment.TemplateRepoName = await QualifyRepoNameAsync(courseId, input.TemplateRepoName, cancellationToken); + + await db.SaveChangesAsync(cancellationToken); + return assignment; + } + + public async Task SetArchivedAsync(int courseId, int assignmentId, bool archived, CancellationToken cancellationToken = default) + { + var assignment = await TrackedAsync(courseId, assignmentId, cancellationToken); + if (assignment is null) + return null; + + assignment.ArchivedAt = archived ? assignment.ArchivedAt ?? DateTimeOffset.UtcNow : null; + await db.SaveChangesAsync(cancellationToken); + return assignment; + } + + public async Task RegenerateInviteTokenAsync(int courseId, int assignmentId, CancellationToken cancellationToken = default) + { + var assignment = await TrackedAsync(courseId, assignmentId, cancellationToken); + if (assignment is null) + return null; + + assignment.InviteToken = TokenGenerator.UrlSafe(18); + await db.SaveChangesAsync(cancellationToken); + return assignment; + } + + public async Task DeleteAsync(int courseId, int assignmentId, CancellationToken cancellationToken = default) + { + var assignment = await TrackedAsync(courseId, assignmentId, cancellationToken); + if (assignment is null) + return false; + + // Repositories exist on GitHub for every acceptance; deleting the record would orphan them and lose the + // audit trail of who got what. Archiving is the operation the instructor actually wants. + var accepted = await db.AssignmentAcceptances.IgnoreQueryFilters() + .AnyAsync(a => a.AssignmentId == assignmentId, cancellationToken); + + if (accepted) + return false; + + db.Assignments.Remove(assignment); + await db.SaveChangesAsync(cancellationToken); + return true; + } + + public async Task> ListAcceptancesAsync(int courseId, int assignmentId, CancellationToken cancellationToken = default) => + await db.AssignmentAcceptances.IgnoreQueryFilters().AsNoTracking() + .Include(a => a.User) + .Where(a => a.CourseId == courseId && a.AssignmentId == assignmentId) + .OrderByDescending(a => a.AcceptedAt) + .ToListAsync(cancellationToken); + + public async Task> CountAcceptancesAsync(int courseId, CancellationToken cancellationToken = default) + { + var counts = await db.AssignmentAcceptances.IgnoreQueryFilters().AsNoTracking() + .Where(a => a.CourseId == courseId) + .GroupBy(a => a.AssignmentId) + .Select(g => new { AssignmentId = g.Key, Count = g.Count() }) + .ToListAsync(cancellationToken); + + return counts.ToDictionary(c => c.AssignmentId, c => c.Count); + } + + public async Task CheckTemplateAsync(int courseId, string templateRepoName, CancellationToken cancellationToken = default) + { + if (string.IsNullOrWhiteSpace(templateRepoName)) + return new TemplateCheck(false, false, null, "No template repository is set."); + + var token = await tokens.GetForCourseAsync(courseId, bypassCache: false, cancellationToken); + if (token is null) + return new TemplateCheck(false, false, null, "This course has no GitHub App configured, so the template cannot be checked."); + + var qualified = await QualifyRepoNameAsync(courseId, templateRepoName, cancellationToken); + var (owner, name) = IAssignmentService.SplitRepoName(qualified); + + try + { + var repository = await gitHub.GetRepositoryAsync(owner, name, token.Token, cancellationToken); + if (repository is null) + return new TemplateCheck(false, false, null, $"GitHub has no repository called '{qualified}', or the App cannot see it."); + + return repository.IsTemplate + ? new TemplateCheck(true, true, repository.HtmlUrl, null) + : new TemplateCheck(true, false, repository.HtmlUrl, $"'{qualified}' exists but is not marked as a template repository. Turn on \"Template repository\" in its settings."); + } + catch (GitHubOperationException ex) + { + return new TemplateCheck(false, false, null, ex.GitHubMessage ?? ex.Message); + } + catch (HttpRequestException ex) + { + return new TemplateCheck(false, false, null, $"GitHub could not be reached: {ex.Message}"); + } + catch (TaskCanceledException) when (!cancellationToken.IsCancellationRequested) + { + return new TemplateCheck(false, false, null, "GitHub did not respond in time."); + } + } + + private async Task TrackedAsync(int courseId, int assignmentId, CancellationToken cancellationToken) => + await db.Assignments.IgnoreQueryFilters() + .FirstOrDefaultAsync(a => a.Id == assignmentId && a.CourseId == courseId, cancellationToken); + + /// + /// Accepts a bare repository name and completes it with the course's organization, so an instructor does + /// not have to retype "ahk-viaubc01/" on every assignment. Always stored normalized, like every other + /// repository name in the model. + /// + private async Task QualifyRepoNameAsync(int courseId, string templateRepoName, CancellationToken cancellationToken) + { + var value = (templateRepoName ?? string.Empty).Trim().Trim('/'); + if (value.Contains('/', StringComparison.Ordinal)) + return Normalize.RepoName(value); + + var organization = await db.Courses.AsNoTracking() + .Where(c => c.Id == courseId) + .Select(c => c.GitHubOrganization) + .FirstOrDefaultAsync(cancellationToken); + + return Normalize.RepoName(string.IsNullOrWhiteSpace(organization) ? value : $"{organization}/{value}"); + } + + private static string? Trimmed(string? value) => string.IsNullOrWhiteSpace(value) ? null : value.Trim(); +} diff --git a/ahk-backend/Ahk.Web.Services/Assignments/StudentAssignmentService.cs b/ahk-backend/Ahk.Web.Services/Assignments/StudentAssignmentService.cs new file mode 100644 index 00000000..2f14628d --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/Assignments/StudentAssignmentService.cs @@ -0,0 +1,233 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Ahk.Web.Services.GitHub; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; + +namespace Ahk.Web.Services.Assignments; + +/// Whether the student can actually open the repository yet. +public enum RepositoryAccess +{ + /// They have push access. + Active, + + /// GitHub has invited them and is waiting; the repository is invisible to them until they accept. + InvitationPending, + + /// The invitation ran out. It has to be re-sent before they can get in. + InvitationExpired, + + /// GitHub could not be asked just now, so the last known state is reported. + Unknown, +} + +/// One repository a student holds, with the course and assignment it belongs to. +public sealed class StudentRepository +{ + public int AcceptanceId { get; set; } + + public string CourseSlug { get; set; } = string.Empty; + + public string CourseName { get; set; } = string.Empty; + + public string AssignmentName { get; set; } = string.Empty; + + public string GitHubRepoName { get; set; } = string.Empty; + + public string RepoUrl { get; set; } = string.Empty; + + public DateTimeOffset AcceptedAt { get; set; } + + public RepositoryAccess Access { get; set; } + + /// Where the student accepts a pending invitation; null once they have access. + public string? InvitationUrl { get; set; } + + public DateTimeOffset? InvitationSentAt { get; set; } +} + +public interface IStudentAssignmentService +{ + Task> ListForUserAsync(int userId, CancellationToken cancellationToken = default); + + /// + /// Issues a fresh invitation for a repository the student still cannot open. Returns null when the + /// acceptance is not theirs or does not exist. + /// + Task ResendInvitationAsync(int userId, int acceptanceId, CancellationToken cancellationToken = default); +} + +/// +/// The student's own view of the system: every repository they hold, across every course, and a way to get back +/// in when a GitHub invitation lapsed before they clicked it. +/// +/// ⚠️ These calls arrive on routes with no {course} segment, so no current course is resolved and the ambient +/// query filter would match nothing. Every read here uses IgnoreQueryFilters() and filters on the user. +/// +public sealed class StudentAssignmentService : IStudentAssignmentService +{ + private readonly ApplicationDbContext db; + private readonly IGitHubRepositoryService gitHub; + private readonly ICourseGitHubAppTokenProvider tokens; + private readonly ILogger logger; + + public StudentAssignmentService( + ApplicationDbContext db, + IGitHubRepositoryService gitHub, + ICourseGitHubAppTokenProvider tokens, + ILogger logger) + { + this.db = db; + this.gitHub = gitHub; + this.tokens = tokens; + this.logger = logger; + } + + public async Task> ListForUserAsync(int userId, CancellationToken cancellationToken = default) + { + var acceptances = await db.AssignmentAcceptances.IgnoreQueryFilters() + .Include(a => a.Assignment) + .Include(a => a.Course) + .Where(a => a.UserId == userId) + .OrderByDescending(a => a.AcceptedAt) + .ToListAsync(cancellationToken); + + var changed = false; + var results = new List(acceptances.Count); + + foreach (var acceptance in acceptances) + { + // Only rows we believe are waiting cost a GitHub call — a student holds a handful of repositories, + // and most of them are settled. + if (acceptance.InvitationPending) + changed |= await RefreshInvitationStateAsync(acceptance, cancellationToken); + + results.Add(Project(acceptance)); + } + + if (changed) + await db.SaveChangesAsync(cancellationToken); + + return results; + } + + public async Task ResendInvitationAsync(int userId, int acceptanceId, CancellationToken cancellationToken = default) + { + var acceptance = await db.AssignmentAcceptances.IgnoreQueryFilters() + .Include(a => a.Assignment) + .Include(a => a.Course) + .FirstOrDefaultAsync(a => a.Id == acceptanceId && a.UserId == userId, cancellationToken); + + if (acceptance is null) + return null; + + var token = await tokens.GetForCourseAsync(acceptance.CourseId, bypassCache: false, cancellationToken); + if (token is null) + { + acceptance.InvitationPending = true; + return Project(acceptance); + } + + var (owner, name) = IAssignmentService.SplitRepoName(acceptance.GitHubRepoName); + + // They may have accepted since the page was drawn; re-sending would then be a pointless invitation. + if (await gitHub.IsCollaboratorAsync(owner, name, acceptance.GitHubUsername, token.Token, cancellationToken)) + { + ClearInvitation(acceptance); + await db.SaveChangesAsync(cancellationToken); + return Project(acceptance); + } + + // GitHub has no "extend"; the stale invitation has to go before a fresh one can be issued. + var existing = await gitHub.FindInvitationAsync(owner, name, acceptance.GitHubUsername, token.Token, cancellationToken); + if (existing is not null) + await gitHub.DeleteInvitationAsync(owner, name, existing.Id, token.Token, cancellationToken); + + var result = await gitHub.AddCollaboratorAsync(owner, name, acceptance.GitHubUsername, token.Token, cancellationToken); + + acceptance.InvitationPending = result.InvitationCreated; + acceptance.InvitationId = result.InvitationId; + acceptance.InvitationSentAt = result.InvitationCreated ? DateTimeOffset.UtcNow : null; + + await db.SaveChangesAsync(cancellationToken); + return Project(acceptance); + } + + /// + /// Asks GitHub what really happened to a pending invitation. Returns true when the stored state changed. + /// Never throws: this runs while rendering the student's home page, and an unreachable GitHub must degrade + /// to "unknown", not to an error page. + /// + private async Task RefreshInvitationStateAsync(AssignmentAcceptance acceptance, CancellationToken cancellationToken) + { + try + { + var token = await tokens.GetForCourseAsync(acceptance.CourseId, bypassCache: false, cancellationToken); + if (token is null) + return false; + + var (owner, name) = IAssignmentService.SplitRepoName(acceptance.GitHubRepoName); + + if (await gitHub.IsCollaboratorAsync(owner, name, acceptance.GitHubUsername, token.Token, cancellationToken)) + { + ClearInvitation(acceptance); + return true; + } + + var invitation = await gitHub.FindInvitationAsync(owner, name, acceptance.GitHubUsername, token.Token, cancellationToken); + + // No access and no invitation at all: it lapsed and GitHub cleaned it up. Treat it as expired so + // the student is offered the resend button rather than left waiting for nothing. + if (invitation is null) + { + acceptance.InvitationId = null; + return true; + } + + if (invitation.Id != acceptance.InvitationId) + { + acceptance.InvitationId = invitation.Id; + return true; + } + + return false; + } + catch (Exception ex) when (ex is GitHubOperationException or HttpRequestException or TaskCanceledException) + { + logger.LogWarning(ex, "Could not refresh the invitation state of {Repository}.", acceptance.GitHubRepoName); + return false; + } + } + + private static void ClearInvitation(AssignmentAcceptance acceptance) + { + acceptance.InvitationPending = false; + acceptance.InvitationId = null; + acceptance.InvitationSentAt = null; + } + + private static StudentRepository Project(AssignmentAcceptance acceptance) + { + var (owner, name) = IAssignmentService.SplitRepoName(acceptance.GitHubRepoName); + + // A pending row with no invitation id left is one GitHub has already dropped: expired, not waiting. + var access = acceptance.InvitationPending + ? acceptance.InvitationId is null ? RepositoryAccess.InvitationExpired : RepositoryAccess.InvitationPending + : RepositoryAccess.Active; + + return new StudentRepository + { + AcceptanceId = acceptance.Id, + CourseSlug = acceptance.Course?.Slug ?? string.Empty, + CourseName = acceptance.Course?.Name ?? string.Empty, + AssignmentName = acceptance.Assignment?.Name ?? string.Empty, + GitHubRepoName = acceptance.GitHubRepoName, + RepoUrl = acceptance.RepoUrl, + AcceptedAt = acceptance.AcceptedAt, + Access = access, + InvitationUrl = acceptance.InvitationPending ? $"https://github.com/{owner}/{name}/invitations" : null, + InvitationSentAt = acceptance.InvitationSentAt, + }; + } +} diff --git a/ahk-backend/Ahk.Web.Services/Courses/WebhookTokenService.cs b/ahk-backend/Ahk.Web.Services/Courses/WebhookTokenService.cs index 14f9227b..155eb88b 100644 --- a/ahk-backend/Ahk.Web.Services/Courses/WebhookTokenService.cs +++ b/ahk-backend/Ahk.Web.Services/Courses/WebhookTokenService.cs @@ -1,4 +1,3 @@ -using System.Security.Cryptography; using Ahk.Web.Data; using Ahk.Web.Data.Entities; using Microsoft.EntityFrameworkCore; @@ -75,8 +74,8 @@ public async Task CreateAsync(int courseId, string? descript var entity = new CourseWebhookToken { CourseId = courseId, - Token = GenerateSecret(24), - Secret = GenerateSecret(32), + Token = TokenGenerator.UrlSafe(24), + Secret = TokenGenerator.UrlSafe(32), Description = description, }; @@ -106,11 +105,4 @@ public async Task RevokeAsync(int courseId, int tokenId, CancellationToken } private static string CacheKey(string token) => $"secrettotoken{token}"; - - /// URL-safe random string — these travel in an HTTP header and a workflow secret. - private static string GenerateSecret(int byteLength) => - Convert.ToBase64String(RandomNumberGenerator.GetBytes(byteLength)) - .Replace('+', '-') - .Replace('/', '_') - .TrimEnd('='); } diff --git a/ahk-backend/Ahk.Web.Services/GitHub/CourseGitHubAppTokenProvider.cs b/ahk-backend/Ahk.Web.Services/GitHub/CourseGitHubAppTokenProvider.cs new file mode 100644 index 00000000..87eaf397 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHub/CourseGitHubAppTokenProvider.cs @@ -0,0 +1,203 @@ +using System.Buffers.Text; +using System.Net.Http.Headers; +using System.Security.Cryptography; +using System.Text; +using System.Text.Json; +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Memory; + +namespace Ahk.Web.Services.GitHub; + +/// An installation access token plus the permissions GitHub actually granted it. +public sealed record GitHubInstallationToken(string Token, long InstallationId, IReadOnlyDictionary Permissions, string? RepositorySelection) +{ + /// + /// True when the installation may create repositories, add collaborators and change repository settings — + /// everything the assignment flow does. Reported by the health check so an administrator sees the gap + /// before a student walks into a 403. + /// + public bool HasAdministrationWrite => + Permissions.TryGetValue("administration", out var level) && string.Equals(level, "write", StringComparison.Ordinal); +} + +public interface ICourseGitHubAppTokenProvider +{ + /// + /// Mints (or returns a cached) installation token for the course's organization. Returns null — never + /// throws — when the course has no GitHub App configured or no organization, so callers can turn that into + /// a clean "this course is not connected to GitHub yet" message. + /// + Task GetForCourseAsync(int courseId, bool bypassCache = false, CancellationToken cancellationToken = default); + + /// Overload for callers that already loaded the course with its . + Task GetForCourseAsync(Course course, bool bypassCache = false, CancellationToken cancellationToken = default); +} + +/// +/// Turns a course's GitHub App credentials into an installation access token, the identity every write the +/// portal performs on GitHub runs as. Port of the flow in +/// github-monitor/.../GitHubClientFactory.cs, with two differences: the installation is looked up from +/// the organization (there is no webhook payload to read it from), and the JWT is built with +/// rather than the hand-rolled DER reader that predates it. +/// +public sealed class CourseGitHubAppTokenProvider : ICourseGitHubAppTokenProvider +{ + /// GitHub issues installation tokens for 60 minutes; renew with room to spare. + private static readonly TimeSpan CacheDuration = TimeSpan.FromMinutes(50); + + private readonly ApplicationDbContext db; + private readonly IHttpClientFactory httpClientFactory; + private readonly IMemoryCache cache; + + public CourseGitHubAppTokenProvider(ApplicationDbContext db, IHttpClientFactory httpClientFactory, IMemoryCache cache) + { + this.db = db; + this.httpClientFactory = httpClientFactory; + this.cache = cache; + } + + public async Task GetForCourseAsync(int courseId, bool bypassCache = false, CancellationToken cancellationToken = default) + { + // Course itself is not course-scoped, but the include is, so this is a plain lookup by primary key. + var course = await db.Courses + .AsNoTracking() + .Include(c => c.GitHubConfig) + .FirstOrDefaultAsync(c => c.Id == courseId, cancellationToken); + + return course is null ? null : await GetForCourseAsync(course, bypassCache, cancellationToken); + } + + public async Task GetForCourseAsync(Course course, bool bypassCache = false, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(course); + + var appId = course.GitHubConfig?.GitHubAppId; + var privateKey = course.GitHubConfig?.GitHubAppPrivateKey; + var organization = course.GitHubOrganization; + + if (string.IsNullOrWhiteSpace(appId) || string.IsNullOrWhiteSpace(privateKey) || string.IsNullOrWhiteSpace(organization)) + return null; + + var key = $"githubinstallationtoken_{course.Id}"; + if (!bypassCache && cache.TryGetValue(key, out var cached) && cached is not null) + return cached; + + var token = await MintAsync(appId, privateKey, organization, cancellationToken); + cache.Set(key, token, CacheDuration); + return token; + } + + private async Task MintAsync(string appId, string privateKey, string organization, CancellationToken cancellationToken) + { + var jwt = CreateAppJwt(appId, privateKey); + + using var client = httpClientFactory.CreateClient(GitHubApiDefaults.HttpClientName); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwt); + + // Which installation of this App owns the course's organization. + using var installationResponse = await client.GetAsync( + new Uri($"orgs/{Uri.EscapeDataString(organization)}/installation", UriKind.Relative), cancellationToken); + await EnsureSuccessAsync(installationResponse, $"looking up the App installation on '{organization}'", cancellationToken); + + using var installationDocument = await ReadJsonAsync(installationResponse, cancellationToken); + var installationId = installationDocument.RootElement.GetProperty("id").GetInt64(); + + // Exchange the App JWT for a token scoped to that installation. + using var tokenResponse = await client.PostAsync( + new Uri($"app/installations/{installationId}/access_tokens", UriKind.Relative), content: null, cancellationToken); + await EnsureSuccessAsync(tokenResponse, "creating an installation access token", cancellationToken); + + using var tokenDocument = await ReadJsonAsync(tokenResponse, cancellationToken); + var root = tokenDocument.RootElement; + + var permissions = new Dictionary(StringComparer.OrdinalIgnoreCase); + if (root.TryGetProperty("permissions", out var permissionsElement) && permissionsElement.ValueKind == JsonValueKind.Object) + { + foreach (var permission in permissionsElement.EnumerateObject()) + permissions[permission.Name] = permission.Value.GetString() ?? string.Empty; + } + + var repositorySelection = root.TryGetProperty("repository_selection", out var selection) ? selection.GetString() : null; + + return new GitHubInstallationToken( + root.GetProperty("token").GetString() ?? string.Empty, + installationId, + permissions, + repositorySelection); + } + + /// + /// The App-level JWT: RS256, ten minutes, issued by the App id. GitHub accepts nothing else at + /// /app/*, and it is only ever used to obtain the installation token. + /// + private static string CreateAppJwt(string appId, string privateKey) + { + var now = DateTimeOffset.UtcNow; + + // 60 seconds of backdating absorbs clock skew between this server and GitHub, which otherwise rejects + // the JWT outright ("'iat' is in the future"). + var header = """{"alg":"RS256","typ":"JWT"}"""; + var payload = $$"""{"iat":{{now.AddSeconds(-60).ToUnixTimeSeconds()}},"exp":{{now.AddMinutes(10).ToUnixTimeSeconds()}},"iss":"{{appId}}"}"""; + + var signingInput = $"{Base64Url.EncodeToString(Encoding.UTF8.GetBytes(header))}.{Base64Url.EncodeToString(Encoding.UTF8.GetBytes(payload))}"; + + using var rsa = ImportPrivateKey(privateKey); + var signature = rsa.SignData(Encoding.UTF8.GetBytes(signingInput), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); + + return $"{signingInput}.{Base64Url.EncodeToString(signature)}"; + } + + /// + /// Accepts either the PEM file GitHub hands out on key creation, or the bare base64 DER body that + /// github-monitor's AHK_GitHubAppPrivateKey holds — an administrator migrating a course should be + /// able to paste what they already have. + /// + private static RSA ImportPrivateKey(string privateKey) + { + var value = privateKey.Trim(); + var rsa = RSA.Create(); + + try + { + if (value.Contains("-----BEGIN", StringComparison.Ordinal)) + { + rsa.ImportFromPem(value); + return rsa; + } + + var der = Convert.FromBase64String(new string(value.Where(c => !char.IsWhiteSpace(c)).ToArray())); + try + { + rsa.ImportRSAPrivateKey(der, out _); + } + catch (CryptographicException) + { + rsa.ImportPkcs8PrivateKey(der, out _); + } + + return rsa; + } + catch + { + rsa.Dispose(); + throw; + } + } + + private static async Task ReadJsonAsync(HttpResponseMessage response, CancellationToken cancellationToken) + { + await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken); + return await JsonDocument.ParseAsync(stream, cancellationToken: cancellationToken); + } + + private static async Task EnsureSuccessAsync(HttpResponseMessage response, string operation, CancellationToken cancellationToken) + { + if (response.IsSuccessStatusCode) + return; + + var message = await GitHubApiDefaults.ReadErrorMessageAsync(response, cancellationToken); + throw new GitHubOperationException(operation, response.StatusCode, message); + } +} diff --git a/ahk-backend/Ahk.Web.Services/GitHub/GitHubApiDefaults.cs b/ahk-backend/Ahk.Web.Services/GitHub/GitHubApiDefaults.cs new file mode 100644 index 00000000..15d534f4 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHub/GitHubApiDefaults.cs @@ -0,0 +1,32 @@ +using System.Text.Json; + +namespace Ahk.Web.Services.GitHub; + +/// Shared constants and helpers for the raw api.github.com calls the portal makes. +public static class GitHubApiDefaults +{ + /// Named registered by AddAhkServices, based at api.github.com. + public const string HttpClientName = "github"; + + /// + /// GitHub's own explanation of a failure, from the message field of its error body. Returns null + /// rather than throwing on an unreadable body — this runs on the error path, where a second failure would + /// only hide the first. + /// + public static async Task ReadErrorMessageAsync(HttpResponseMessage response, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(response); + + try + { + await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken); + using var document = await JsonDocument.ParseAsync(stream, cancellationToken: cancellationToken); + + return document.RootElement.TryGetProperty("message", out var message) ? message.GetString() : null; + } + catch (Exception ex) when (ex is JsonException or HttpRequestException or InvalidOperationException) + { + return null; + } + } +} diff --git a/ahk-backend/Ahk.Web.Services/GitHub/GitHubOperationException.cs b/ahk-backend/Ahk.Web.Services/GitHub/GitHubOperationException.cs new file mode 100644 index 00000000..510f53f3 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHub/GitHubOperationException.cs @@ -0,0 +1,43 @@ +using System.Net; + +namespace Ahk.Web.Services.GitHub; + +/// +/// A GitHub call that was expected to succeed did not. Carries GitHub's own status and message so the caller +/// can tell a student something true ("the organization does not allow this") rather than "something failed". +/// +public sealed class GitHubOperationException : Exception +{ + public GitHubOperationException(string operation, HttpStatusCode status, string? gitHubMessage) + : base(BuildMessage(operation, status, gitHubMessage)) + { + Operation = operation; + Status = status; + GitHubMessage = gitHubMessage; + } + + public GitHubOperationException() + { + } + + public GitHubOperationException(string message) + : base(message) + { + } + + public GitHubOperationException(string message, Exception innerException) + : base(message, innerException) + { + } + + public string? Operation { get; } + + public HttpStatusCode Status { get; } + + public string? GitHubMessage { get; } + + private static string BuildMessage(string operation, HttpStatusCode status, string? gitHubMessage) => + string.IsNullOrWhiteSpace(gitHubMessage) + ? $"GitHub returned {(int)status} {status} for {operation}." + : $"GitHub returned {(int)status} {status} for {operation}: {gitHubMessage}"; +} diff --git a/ahk-backend/Ahk.Web.Services/GitHub/GitHubRepositoryService.cs b/ahk-backend/Ahk.Web.Services/GitHub/GitHubRepositoryService.cs new file mode 100644 index 00000000..231c922c --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHub/GitHubRepositoryService.cs @@ -0,0 +1,262 @@ +using System.Net; +using System.Net.Http.Headers; +using System.Net.Http.Json; +using System.Text.Json; + +namespace Ahk.Web.Services.GitHub; + +/// A GitHub account, as much of it as this application cares about. +public sealed record GitHubUser(string Login, long Id); + +/// A GitHub repository, as much of it as this application cares about. +public sealed record GitHubRepository(string FullName, string HtmlUrl, bool IsTemplate, string? DefaultBranch); + +/// +/// Outcome of sharing a repository with a student. GitHub adds an organization member outright (204) but only +/// *invites* anyone else (201) — and that invitation expires, so the two cases are not interchangeable. +/// +public sealed record CollaboratorResult(bool InvitationCreated, long? InvitationId); + +/// A pending repository invitation. +public sealed record GitHubInvitation(long Id, string? InviteeLogin, bool Expired, DateTimeOffset? CreatedAt); + +public interface IGitHubRepositoryService +{ + /// The account behind a login, or null when there is none. This is the typo check. + Task GetUserAsync(string login, string? token, CancellationToken cancellationToken = default); + + /// The repository, or null when it does not exist (or the token cannot see it). + Task GetRepositoryAsync(string owner, string name, string token, CancellationToken cancellationToken = default); + + /// Creates a private repository from a template repository. The template must be marked as one. + Task GenerateFromTemplateAsync(string templateOwner, string templateName, string owner, string name, string token, CancellationToken cancellationToken = default); + + /// Turns Actions on for a repository. Cheap insurance; a freshly generated repository normally has it already. + Task EnsureActionsEnabledAsync(string owner, string name, string token, CancellationToken cancellationToken = default); + + /// Grants a login push access, directly or by invitation depending on organization membership. + Task AddCollaboratorAsync(string owner, string name, string login, string token, CancellationToken cancellationToken = default); + + /// Whether the login already has access — the definitive answer to "did they accept the invitation". + Task IsCollaboratorAsync(string owner, string name, string login, string token, CancellationToken cancellationToken = default); + + /// The outstanding invitation for a login, or null when there is none. + Task FindInvitationAsync(string owner, string name, string login, string token, CancellationToken cancellationToken = default); + + Task DeleteInvitationAsync(string owner, string name, long invitationId, string token, CancellationToken cancellationToken = default); +} + +/// +/// The GitHub REST calls the assignment flow needs, over the shared named . Deliberately +/// raw HttpClient + System.Text.Json rather than Octokit: this is the idiom the portal already +/// uses (see Health/GitHubAccessHealthCheck) and a handful of endpoints does not justify a dependency. +/// +/// Every method takes the caller's installation token explicitly rather than resolving a course itself, so the +/// service stays a thin, testable transport with no ambient state. +/// +public sealed class GitHubRepositoryService : IGitHubRepositoryService +{ + private readonly IHttpClientFactory httpClientFactory; + + public GitHubRepositoryService(IHttpClientFactory httpClientFactory) => this.httpClientFactory = httpClientFactory; + + public async Task GetUserAsync(string login, string? token, CancellationToken cancellationToken = default) + { + using var client = CreateClient(token); + using var response = await client.GetAsync(Relative($"users/{Uri.EscapeDataString(login)}"), cancellationToken); + + if (response.StatusCode == HttpStatusCode.NotFound) + return null; + + await EnsureSuccessAsync(response, $"looking up the GitHub user '{login}'", cancellationToken); + + using var document = await ReadJsonAsync(response, cancellationToken); + return new GitHubUser( + document.RootElement.GetProperty("login").GetString() ?? login, + document.RootElement.GetProperty("id").GetInt64()); + } + + public async Task GetRepositoryAsync(string owner, string name, string token, CancellationToken cancellationToken = default) + { + using var client = CreateClient(token); + using var response = await client.GetAsync(Relative($"repos/{Uri.EscapeDataString(owner)}/{Uri.EscapeDataString(name)}"), cancellationToken); + + if (response.StatusCode == HttpStatusCode.NotFound) + return null; + + await EnsureSuccessAsync(response, $"reading the repository '{owner}/{name}'", cancellationToken); + + using var document = await ReadJsonAsync(response, cancellationToken); + return ReadRepository(document.RootElement, $"{owner}/{name}"); + } + + public async Task GenerateFromTemplateAsync(string templateOwner, string templateName, string owner, string name, string token, CancellationToken cancellationToken = default) + { + using var client = CreateClient(token); + + // include_all_branches stays false: the student starts from the template's default branch, which is + // what the evaluator and the branch-protection rules assume. + var body = new + { + owner, + name, + @private = true, + include_all_branches = false, + }; + + using var response = await client.PostAsJsonAsync( + Relative($"repos/{Uri.EscapeDataString(templateOwner)}/{Uri.EscapeDataString(templateName)}/generate"), + body, + cancellationToken); + + await EnsureSuccessAsync(response, $"creating '{owner}/{name}' from the template '{templateOwner}/{templateName}'", cancellationToken); + + using var document = await ReadJsonAsync(response, cancellationToken); + return ReadRepository(document.RootElement, $"{owner}/{name}"); + } + + public async Task EnsureActionsEnabledAsync(string owner, string name, string token, CancellationToken cancellationToken = default) + { + using var client = CreateClient(token); + using var response = await client.PutAsJsonAsync( + Relative($"repos/{Uri.EscapeDataString(owner)}/{Uri.EscapeDataString(name)}/actions/permissions"), + new { enabled = true }, + cancellationToken); + + await EnsureSuccessAsync(response, $"enabling Actions on '{owner}/{name}'", cancellationToken); + } + + public async Task AddCollaboratorAsync(string owner, string name, string login, string token, CancellationToken cancellationToken = default) + { + using var client = CreateClient(token); + using var response = await client.PutAsJsonAsync( + Relative($"repos/{Uri.EscapeDataString(owner)}/{Uri.EscapeDataString(name)}/collaborators/{Uri.EscapeDataString(login)}"), + new { permission = "push" }, + cancellationToken); + + await EnsureSuccessAsync(response, $"granting '{login}' access to '{owner}/{name}'", cancellationToken); + + // 204 means the login was added outright (they are already an organization member). 201 means an + // invitation was created and the repository stays invisible to them until they accept it. + if (response.StatusCode == HttpStatusCode.NoContent) + return new CollaboratorResult(InvitationCreated: false, InvitationId: null); + + using var document = await ReadJsonAsync(response, cancellationToken); + var id = document.RootElement.TryGetProperty("id", out var idElement) ? idElement.GetInt64() : (long?)null; + return new CollaboratorResult(InvitationCreated: true, InvitationId: id); + } + + public async Task IsCollaboratorAsync(string owner, string name, string login, string token, CancellationToken cancellationToken = default) + { + using var client = CreateClient(token); + using var response = await client.GetAsync( + Relative($"repos/{Uri.EscapeDataString(owner)}/{Uri.EscapeDataString(name)}/collaborators/{Uri.EscapeDataString(login)}"), + cancellationToken); + + if (response.StatusCode is HttpStatusCode.NoContent or HttpStatusCode.OK) + return true; + + if (response.StatusCode == HttpStatusCode.NotFound) + return false; + + await EnsureSuccessAsync(response, $"checking whether '{login}' can access '{owner}/{name}'", cancellationToken); + return false; + } + + public async Task FindInvitationAsync(string owner, string name, string login, string token, CancellationToken cancellationToken = default) + { + using var client = CreateClient(token); + using var response = await client.GetAsync( + Relative($"repos/{Uri.EscapeDataString(owner)}/{Uri.EscapeDataString(name)}/invitations"), + cancellationToken); + + if (response.StatusCode == HttpStatusCode.NotFound) + return null; + + await EnsureSuccessAsync(response, $"listing invitations of '{owner}/{name}'", cancellationToken); + + using var document = await ReadJsonAsync(response, cancellationToken); + if (document.RootElement.ValueKind != JsonValueKind.Array) + return null; + + foreach (var element in document.RootElement.EnumerateArray()) + { + var invitee = element.TryGetProperty("invitee", out var inviteeElement) && inviteeElement.ValueKind == JsonValueKind.Object + ? inviteeElement.GetProperty("login").GetString() + : null; + + if (!string.Equals(invitee, login, StringComparison.OrdinalIgnoreCase)) + continue; + + // GitHub reports expiry itself. Never compute it here: the window is GitHub's policy to change, + // and a stale local constant would have the portal telling students something untrue. + var expired = element.TryGetProperty("expired", out var expiredElement) + && expiredElement.ValueKind == JsonValueKind.True; + + var createdAt = element.TryGetProperty("created_at", out var createdElement) + && createdElement.TryGetDateTimeOffset(out var parsed) + ? parsed + : (DateTimeOffset?)null; + + return new GitHubInvitation(element.GetProperty("id").GetInt64(), invitee, expired, createdAt); + } + + return null; + } + + public async Task DeleteInvitationAsync(string owner, string name, long invitationId, string token, CancellationToken cancellationToken = default) + { + using var client = CreateClient(token); + using var response = await client.DeleteAsync( + Relative($"repos/{Uri.EscapeDataString(owner)}/{Uri.EscapeDataString(name)}/invitations/{invitationId}"), + cancellationToken); + + // Already gone is the desired state, not a failure — the student may have accepted it meanwhile. + if (response.StatusCode == HttpStatusCode.NotFound) + return; + + await EnsureSuccessAsync(response, $"withdrawing invitation {invitationId} on '{owner}/{name}'", cancellationToken); + } + + private static Uri Relative(string path) => new(path, UriKind.Relative); + + private static GitHubRepository ReadRepository(JsonElement element, string fallbackFullName) + { + var fullName = element.TryGetProperty("full_name", out var full) ? full.GetString() : null; + var htmlUrl = element.TryGetProperty("html_url", out var url) ? url.GetString() : null; + var isTemplate = element.TryGetProperty("is_template", out var template) && template.ValueKind == JsonValueKind.True; + var defaultBranch = element.TryGetProperty("default_branch", out var branch) ? branch.GetString() : null; + + return new GitHubRepository( + fullName ?? fallbackFullName, + htmlUrl ?? $"https://github.com/{fullName ?? fallbackFullName}", + isTemplate, + defaultBranch); + } + + private HttpClient CreateClient(string? token) + { + var client = httpClientFactory.CreateClient(GitHubApiDefaults.HttpClientName); + + // GET /users/{login} works unauthenticated; it just drops from 5000 to 60 requests an hour. + if (!string.IsNullOrWhiteSpace(token)) + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); + + return client; + } + + private static async Task ReadJsonAsync(HttpResponseMessage response, CancellationToken cancellationToken) + { + await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken); + return await JsonDocument.ParseAsync(stream, cancellationToken: cancellationToken); + } + + private static async Task EnsureSuccessAsync(HttpResponseMessage response, string operation, CancellationToken cancellationToken) + { + if (response.IsSuccessStatusCode) + return; + + var message = await GitHubApiDefaults.ReadErrorMessageAsync(response, cancellationToken); + throw new GitHubOperationException(operation, response.StatusCode, message); + } +} diff --git a/ahk-backend/Ahk.Web.Services/Health/GitHubAppInstallationHealthCheck.cs b/ahk-backend/Ahk.Web.Services/Health/GitHubAppInstallationHealthCheck.cs new file mode 100644 index 00000000..e0b9cde4 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/Health/GitHubAppInstallationHealthCheck.cs @@ -0,0 +1,123 @@ +using Ahk.Web.Data.Entities; +using Ahk.Web.Services.GitHub; + +namespace Ahk.Web.Services.Health; + +/// +/// Verifies the course's GitHub App can actually act on its organization: that the credentials mint an +/// installation token at all, that the installation covers every repository, and that it was granted +/// administration: write. +/// +/// That last one is the whole point. Creating a repository from a template and adding a student as a +/// collaborator both sit behind it, so without this check the first sign of a missing permission would be a +/// student staring at a failed invite. Here an administrator sees it on the dashboard instead. +/// +public sealed class GitHubAppInstallationHealthCheck : ICourseHealthCheck +{ + /// The dashboard runs every course at once; no single check may hold it open. + private static readonly TimeSpan Budget = TimeSpan.FromSeconds(10); + + private readonly ICourseGitHubAppTokenProvider tokens; + + public GitHubAppInstallationHealthCheck(ICourseGitHubAppTokenProvider tokens) => this.tokens = tokens; + + public string Id => "github-app-installation"; + + public string Title => "GitHub App installation"; + + public int Order => 25; + + public async Task RunAsync(Course course, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(course); + + if (string.IsNullOrWhiteSpace(course.GitHubConfig?.GitHubAppId) || string.IsNullOrWhiteSpace(course.GitHubConfig?.GitHubAppPrivateKey)) + { + return HealthCheckResult.NotConfigured( + this, + "No GitHub App id and private key are stored for this course.", + "Register a GitHub App for the organization and add its id and private key under GitHub integration. See docs/github-app.md."); + } + + if (string.IsNullOrWhiteSpace(course.GitHubOrganization)) + { + return HealthCheckResult.Failed( + this, + "The course has no GitHub organization, so the App installation cannot be located.", + "Set the course's GitHub organization."); + } + + using var timeout = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); + timeout.CancelAfter(Budget); + + try + { + // bypassCache: a health check that reports a cached success from 40 minutes ago is not a health check. + var token = await tokens.GetForCourseAsync(course, bypassCache: true, timeout.Token); + if (token is null) + { + return HealthCheckResult.NotConfigured( + this, + "The GitHub App is not fully configured for this course.", + "Check the App id, private key and organization under GitHub integration."); + } + + var granted = token.Permissions.Count == 0 + ? "none" + : string.Join(", ", token.Permissions.OrderBy(p => p.Key, StringComparer.Ordinal).Select(p => $"{p.Key}: {p.Value}")); + + if (!token.HasAdministrationWrite) + { + return HealthCheckResult.Failed( + this, + $"Installation {token.InstallationId} works, but it was not granted 'administration: write'. Assignments cannot create repositories or add students. Granted: {granted}.", + "Edit the App's repository permissions, set Administration to Read & write, and accept the new permissions on the organization's installation."); + } + + // "selected" means new repositories fall outside the installation, so the collaborator call that + // follows repository creation would 404 on a repository the App itself just made. + if (!string.Equals(token.RepositorySelection, "all", StringComparison.Ordinal)) + { + return HealthCheckResult.Warning( + this, + $"Installation {token.InstallationId} is limited to selected repositories, so repositories created for students fall outside it.", + "Change the installation's repository access to 'All repositories'."); + } + + return HealthCheckResult.Healthy(this, $"Installation {token.InstallationId} covers all repositories and can administer them."); + } + catch (GitHubOperationException ex) + { + return HealthCheckResult.Failed(this, ex.Message, RemediationFor(ex)); + } + catch (System.Security.Cryptography.CryptographicException ex) + { + return HealthCheckResult.Failed( + this, + $"The stored private key could not be read: {ex.Message}", + "Re-download the App's private key (.pem) from GitHub and paste its full contents under GitHub integration."); + } + catch (FormatException) + { + return HealthCheckResult.Failed( + this, + "The stored private key is not valid PEM or base64.", + "Re-download the App's private key (.pem) from GitHub and paste its full contents under GitHub integration."); + } + catch (HttpRequestException ex) + { + return HealthCheckResult.Failed(this, $"GitHub could not be reached: {ex.Message}", "Check network access from the server to api.github.com."); + } + catch (TaskCanceledException) when (!cancellationToken.IsCancellationRequested) + { + return HealthCheckResult.Failed(this, "GitHub did not respond within 10 seconds.", "Check network access from the server to api.github.com."); + } + } + + private static string RemediationFor(GitHubOperationException ex) => ex.Status switch + { + System.Net.HttpStatusCode.NotFound => "The App is registered but not installed on this organization. Install it, with access to all repositories.", + System.Net.HttpStatusCode.Unauthorized => "The App id or private key is wrong, or the key was revoked. Generate a new key and store it again.", + _ => "Check the App registration and its installation on the organization.", + }; +} diff --git a/ahk-backend/Ahk.Web.Services/ServiceCollectionExtensions.cs b/ahk-backend/Ahk.Web.Services/ServiceCollectionExtensions.cs index 2e892f1b..84cad879 100644 --- a/ahk-backend/Ahk.Web.Services/ServiceCollectionExtensions.cs +++ b/ahk-backend/Ahk.Web.Services/ServiceCollectionExtensions.cs @@ -1,5 +1,7 @@ using System.Net.Http.Headers; +using Ahk.Web.Services.Assignments; using Ahk.Web.Services.Courses; +using Ahk.Web.Services.GitHub; using Ahk.Web.Services.Grading; using Ahk.Web.Services.Health; using Ahk.Web.Services.StatusTracking; @@ -21,11 +23,40 @@ public static IServiceCollection AddAhkServices(this IServiceCollection services services.AddScoped(); services.AddScoped(); + services.AddAhkGitHubApi(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddAhkCourseHealthChecks(); return services; } + /// + /// The GitHub REST transport shared by the assignment flow: a named client based at api.github.com and the + /// per-course installation-token provider that authenticates it. + /// + public static IServiceCollection AddAhkGitHubApi(this IServiceCollection services) + { + services.AddHttpClient(GitHubApiDefaults.HttpClientName, client => + { + client.BaseAddress = new Uri("https://api.github.com/"); + client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("ahk-portal", "1.0")); + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.github+json")); + client.DefaultRequestHeaders.Add("X-GitHub-Api-Version", "2022-11-28"); + + // Longer than the health client's 10s: creating a repository from a template is a write, and a + // student is watching a spinner rather than a dashboard of many courses. + client.Timeout = TimeSpan.FromSeconds(30); + }); + + services.AddScoped(); + services.AddScoped(); + + return services; + } + /// /// Registers the course health checks and the service that runs them. Adding a check to the admin /// dashboard is one line here plus the class itself — the service discovers checks through DI. @@ -45,6 +76,7 @@ public static IServiceCollection AddAhkCourseHealthChecks(this IServiceCollectio services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); diff --git a/ahk-backend/README.md b/ahk-backend/README.md index 410f3272..7e5cb869 100644 --- a/ahk-backend/README.md +++ b/ahk-backend/README.md @@ -5,11 +5,12 @@ per-course Azure Functions deployments with a single site whose domain data is a **Courses**. Provides ASP.NET Identity authentication (local username/password + generic OIDC, cookie-based) and course-scoped, membership-authorized endpoints. -> Milestone status: auth, course-scoping, the domain model and services, the read endpoints, and the +> Milestone status: auth, course-scoping, the domain model and services, the read endpoints, the > site administration surface (courses, GitHub integration, CI callback tokens, users, health checks) -> are in place. The write-side entry points — the GitHub webhook receiver, `/ahk ok` chatops and the -> HMAC-verified CI callback — are ported in a later milestone. See the architecture plan for the full -> design. +> and **assignments** (the GitHub Classroom replacement: template repositories, invite links, student +> self-service) are in place. The write-side entry points — the GitHub webhook receiver, `/ahk ok` +> chatops and the HMAC-verified CI callback — are ported in a later milestone. See the architecture +> plan for the full design. ## Projects @@ -17,7 +18,9 @@ cookie-based) and course-scoped, membership-authorized endpoints. `Admin/` (host-context course, user and health management), `Courses/` (course-context endpoints), `CourseContext/` (course resolution middleware + membership authorization). - **Ahk.Web.Services** — domain logic: grading, status tracking, submission resolution, course - resolution, CI callback tokens, and `Health/` (the course health checks). + resolution, CI callback tokens, `Assignments/` (assignment administration and the student invite + flow), `GitHub/` (the App installation-token provider and the REST calls it authenticates), and + `Health/` (the course health checks). - **Ahk.Web.Data** — EF Core `ApplicationDbContext` (Identity + `Course`/`CourseMembership` + `ICourseScoped` global query filter), migrations, and the dev data seeder. - **Ahk.Web.Server.Tests** — xUnit tests (course-scoping unit tests, health-check tests, grade parity @@ -112,12 +115,45 @@ one class plus one registration line** — the controller and the UI need no cha |---|---| | `github-webhook-config` | The course has an organization to route deliveries from, a secret to validate their signature, and the integration is on. Local | | `github-access-token` | `GET /user` and `GET /orgs/{org}` against api.github.com with the stored token. Network, 10s timeout | +| `github-app-installation` | The App credentials mint an installation token, the installation covers **all** repositories, and it was granted `administration: write` — without which assignments cannot create repositories. Network, 10s timeout | | `ci-callback-token` | At least one non-revoked `CourseWebhookToken` exists, so evaluation results are still accepted | Results carry a status (`Healthy` / `Warning` / `Failed` / `NotConfigured`), a message, and a remediation line; a course's overall status is the worst of its checks. Checks must not throw — a failure is a `Failed` result, so one unreachable course cannot take the dashboard down. +## Assignments (the GitHub Classroom replacement) + +Instructors define assignments against a template repository and hand out an invite link; students +follow it and the portal creates their repository. **`docs/github-app.md` is the reference for the +GitHub App this depends on** — registration, permissions, installation scope and troubleshooting. + +| Route | Authorization | Purpose | +|---|---|---| +| `/api/{course}/assignments` | `CourseMember` | Instructor CRUD, archive/unarchive, regenerate invite link, acceptance roster | +| `/api/{course}/invite/{token}` | **`[Authorize]` only** | The student flow: state, then `POST accept` | +| `/api/my/assignments` | `[Authorize]` | Every repository the caller holds, across courses, plus `POST {id}/resend-invitation` | +| `/api/profile/github` | `[Authorize]` | Records the caller's GitHub username after verifying it exists | + +Three things about this are deliberate and easy to break: + +- **The invite and `/my` endpoints must not require course membership.** Accepting an assignment is + how a student first appears in a course at all, so gating them on `CourseMember` locks every + student out of the only endpoints meant for them. The invite *token* is the capability. +- **`/api/my/...` has no `{course}` segment**, so no current course is resolved and the course query + filter matches nothing. `StudentAssignmentService` reads with `IgnoreQueryFilters()` and filters on + the user id; a "helpful" cleanup that removes those calls silently returns zero rows. +- **Assignments are additive.** Repositories created outside the portal keep working exactly as + before — nothing in grading or status tracking may start requiring an `Assignment` row. + +Accepting is idempotent: the repository is looked up on GitHub before it is created, and a unique +index on `(AssignmentId, UserId)` settles the double-click race. Student repositories are private and +named `{template repository name}-{neptun}`, lower-cased like every other repository name in the model. + +Students who are not organization members receive a GitHub *invitation* rather than direct access, and +invitations expire. That state is tracked per acceptance and re-sendable from `/my`; the expiry is read +from GitHub's own `expired` flag, never computed here. + ## Auth model - Cookie-based ASP.NET Identity (the API returns 401/403 rather than redirecting). We intentionally diff --git a/ahk-backend/docs/github-app.md b/ahk-backend/docs/github-app.md new file mode 100644 index 00000000..8b42b9b3 --- /dev/null +++ b/ahk-backend/docs/github-app.md @@ -0,0 +1,167 @@ +# The AHK GitHub App + +Every course in the portal acts on GitHub through a **GitHub App installed on that course's organization**. This +document covers what the App is for, how to register and install one, which permissions it needs and why, and +what to check when something does not work. + +Read this before setting up a new course. The health dashboard in Site administration checks most of what is +described here, but it can only tell you *that* something is wrong — this explains what to do about it. + +## Why an App, and why one per course + +Each course points at its own GitHub organization (`Course.GitHubOrganization`), and each organization is +administered by different people. A single shared credential would give every course's staff power over every +other course's repositories, and would die the day the person who created it left the university. + +A GitHub App avoids both problems: it is owned by the organization rather than a person, its permissions are +declared up front and visible to the organization's owners, and it can be uninstalled by them at any time +without touching any other course. + +The App is used for two things: + +| Purpose | Status | +|---|---| +| Receiving webhooks (pushes, pull requests, comments, workflow runs) and enforcing the course's rules | Live today in `github-monitor`; the receiver is **not yet ported** to the portal | +| Creating student repositories from an assignment's template and granting students access | Live in the portal (this feature) | + +One App can serve both. If the organization already has an App registered for `github-monitor`, extend that one +rather than registering a second — see [Permissions](#permissions) for the single grant that has to be added. + +## Registering the App + +Do this once per organization, as an organization owner. + +1. Go to the organization's **Settings → Developer settings → GitHub Apps → New GitHub App**. +2. **GitHub App name** — something identifiable, e.g. `AHK viaubc01`. +3. **Homepage URL** — `https://ahk.aut.bme.hu`. +4. **Webhook** + - Tick **Active**. + - **Webhook URL**: `https://ahk.aut.bme.hu/api/integrations/github`. + ⚠️ This path is reserved but **the receiver is not implemented in the portal yet**. Until it is, point the + webhook at the course's existing `github-monitor` Function URL instead, and keep using that. + - **Webhook secret**: generate a long random string. You will need it again in step 8. +5. **Permissions** — set exactly what the [table below](#permissions) lists. Nothing more: an App with rights + nobody uses is a liability, and organization owners are shown this list when they install it. +6. **Subscribe to events** — only needed for the webhook side: *Pull request*, *Pull request review*, + *Issue comment*, *Push*, *Create*, *Repository*, *Workflow run*. +7. **Where can this GitHub App be installed?** — *Only on this account*. +8. Create it, then on the App's page: + - Note the **App ID**. + - **Generate a private key**. GitHub downloads a `.pem` file — this is the only time you can get it. + +## Installing it + +On the App's page choose **Install App** and pick the organization. + +**Repository access must be “All repositories”.** + +This is not a convenience setting. Repositories created for students do not exist when the App is installed, so +under *Only select repositories* they fall outside the installation — the portal creates the repository +successfully and then gets a `404` from the very next call, trying to add the student to a repository it just +made itself. The health check reports this as a warning before it happens. + +## Permissions + +Set these under **Repository permissions**. Organization permissions are not needed at all. + +| Permission | Level | Why | +|---|---|---| +| **Administration** | **Read & write** | Creating a repository from a template (`POST /repos/{owner}/{repo}/generate`), adding a student as a collaborator (`PUT /repos/{owner}/{repo}/collaborators/{username}`), managing their invitations, and setting a repository's Actions permissions all sit behind this one. **This is the grant to add if the App already exists for `github-monitor`.** | +| **Metadata** | Read-only | Mandatory for every App. Also backs `GET /repos/{owner}/{repo}`, which the portal uses to check the template exists and is marked as a template. | +| **Contents** | Read-only | Reading the template repository. `github-monitor` needs **Read & write** here for its own work. | +| Pull requests | Read & write | `github-monitor` only: comments, merges, assignees. | +| Issues | Read & write | `github-monitor` only: issue comments carry the `/ahk ok` chatops. | +| Actions | Read-only | `github-monitor` only: counting workflow runs against the course threshold. | + +Note that **Administration: write is broad** — it also permits changing repository settings and deleting +repositories. There is no narrower permission that covers creating repositories and adding collaborators, so +this is the floor, not a choice. + +Verifying a student's GitHub username (`GET /users/{login}`) needs no permission at all. The portal sends the +installation token anyway, purely to get GitHub's authenticated rate limit of 5000 requests an hour instead of +the anonymous 60. + +## Storing the credentials in the portal + +**Site administration → Courses → *course* → GitHub integration**: + +- **GitHub App id** — the App ID from the App's page. +- **GitHub App private key** — paste the entire contents of the `.pem` file, `-----BEGIN` line included. The + bare base64 body that `github-monitor`'s `AHK_GitHubAppPrivateKey` holds is also accepted, so a course being + migrated can paste what it already has. +- **Webhook secret** — the string from step 4. + +Stored credentials are never sent back to the browser. An empty field means *leave the stored value alone*; use +the explicit **Clear** control to remove one. That is what makes saving an untouched form safe. + +Never commit these anywhere. In production the connection string and any process-level secrets come from +environment variables; the App credentials live only in the database. + +## How the portal authenticates + +Each call runs as the App's *installation* on the course's organization: + +1. Build a short-lived **App JWT** — RS256, ten minutes, signed with the private key, issued by the App id. +2. `GET /orgs/{org}/installation` with that JWT → the installation id for the course's organization. +3. `POST /app/installations/{id}/access_tokens` → an **installation access token**, valid for 60 minutes. +4. The token is cached per course for 50 minutes and reused. + +The App JWT never leaves step 1–3; every repository operation uses the installation token. The code is +`Ahk.Web.Services/GitHub/CourseGitHubAppTokenProvider.cs`. + +## Template repository requirements + +An assignment points at a template repository in the course's organization. It must: + +- be marked **Template repository** in its Settings (`is_template: true`) — without this GitHub refuses the + generate call outright; +- contain the evaluator workflow under `.github/workflows/`; +- contain `.github/ahk-monitor.yml` with `enabled: true`, or `github-monitor` will ignore every event from the + repositories generated from it; +- have the branch students should start from as its **default branch** — only that branch is copied. + +The assignment editor checks the first point when you save, and reports it as a warning rather than blocking: +an assignment may legitimately be drafted before its template exists. + +Student repositories are created **private**, named `{template repository name}-{neptun}` in lower case. + +## Repository invitations + +When a student accepts an assignment the portal grants them `push` on their repository. GitHub then does one of +two things: + +- the student is already an **organization member** → they are added outright (`204`) and can open the + repository immediately; +- they are **not** → GitHub creates an **invitation** (`201`). Until they accept it at + `https://github.com/{owner}/{repo}/invitations`, the repository 404s for them. + +Invitations expire (7 days at the time of writing). The portal tracks the pending state per acceptance, and the +student's own page (`/my`) shows it with a **Resend invitation** button. GitHub has no way to extend an +invitation, so re-sending withdraws the stale one and issues a fresh one. + +The portal never computes the expiry window itself — it reads GitHub's `expired` flag on the invitation. If +GitHub changes the policy, nothing here has to change. + +## Troubleshooting + +The admin health dashboard runs four checks per course. Each maps to something in this document: + +| Check | What it means when it fails | +|---|---| +| **Webhook settings** | No webhook secret stored — incoming webhooks cannot be verified. Step 4 and *Storing the credentials*. | +| **GitHub access token** | The course's personal access token is invalid or cannot see the organization. Independent of the App; used only for this check today. | +| **GitHub App installation** | The App credentials do not work, the App is not installed on the organization, it lacks `administration: write`, or the installation is limited to selected repositories. Everything above. | +| **CI callback token** | No token for evaluation results to be signed with. Unrelated to the App. | + +Specific failures: + +- **“Installation … was not granted 'administration: write'”** — edit the App's repository permissions, then + accept the new permissions on the organization's installation page. GitHub does **not** apply added + permissions until an owner approves them, so changing the App alone is not enough. +- **404 from `GET /orgs/{org}/installation`** — the App is registered but not installed on that organization, + or the course's organization name is wrong. +- **401 from the token endpoint** — wrong App id, or the private key was revoked or pasted incompletely. + Generate a new key and store it again. +- **“limited to selected repositories”** — change the installation's repository access to *All repositories*. +- **Student says the repository 404s** — they almost certainly have an unaccepted invitation. Point them at + `/my` on the portal. diff --git a/ahk-frontend/src/app/api/api-client.ts b/ahk-frontend/src/app/api/api-client.ts index 51d95033..72c6f532 100644 --- a/ahk-frontend/src/app/api/api-client.ts +++ b/ahk-frontend/src/app/api/api-client.ts @@ -14,6 +14,862 @@ import { HttpClient, HttpHeaders, HttpResponse, HttpResponseBase } from '@angula export const API_BASE_URL = new InjectionToken('API_BASE_URL'); +export interface IMyAssignmentsClient { + list(): Observable; + resendInvitation(id: number): Observable; +} + +@Injectable({ + providedIn: 'root' +}) +export class MyAssignmentsClient implements IMyAssignmentsClient { + private http: HttpClient; + private baseUrl: string; + protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; + + constructor(@Inject(HttpClient) http: HttpClient, @Optional() @Inject(API_BASE_URL) baseUrl?: string) { + this.http = http; + this.baseUrl = baseUrl ?? "https://localhost:7443"; + } + + list(): Observable { + let url_ = this.baseUrl + "/api/my/assignments"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processList(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processList(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processList(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as StudentRepository[]; + return _observableOf(result200); + })); + } else if (status === 401) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result401: any = null; + result401 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result401); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + resendInvitation(id: number): Observable { + let url_ = this.baseUrl + "/api/my/assignments/{id}/resend-invitation"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("post", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processResendInvitation(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processResendInvitation(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processResendInvitation(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as StudentRepository; + return _observableOf(result200); + })); + } else if (status === 401) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result401: any = null; + result401 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result401); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status === 502) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("A server side error occurred.", status, _responseText, _headers); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } +} + +export interface IAssignmentInviteClient { + get(token: string, course: string): Observable; + accept(token: string, course: string): Observable; +} + +@Injectable({ + providedIn: 'root' +}) +export class AssignmentInviteClient implements IAssignmentInviteClient { + private http: HttpClient; + private baseUrl: string; + protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; + + constructor(@Inject(HttpClient) http: HttpClient, @Optional() @Inject(API_BASE_URL) baseUrl?: string) { + this.http = http; + this.baseUrl = baseUrl ?? "https://localhost:7443"; + } + + get(token: string, course: string): Observable { + let url_ = this.baseUrl + "/api/{course}/invite/{token}"; + if (token === undefined || token === null) + throw new globalThis.Error("The parameter 'token' must be defined."); + url_ = url_.replace("{token}", encodeURIComponent("" + token)); + if (course === undefined || course === null) + throw new globalThis.Error("The parameter 'course' must be defined."); + url_ = url_.replace("{course}", encodeURIComponent("" + course)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processGet(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processGet(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processGet(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as InviteState; + return _observableOf(result200); + })); + } else if (status === 401) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result401: any = null; + result401 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result401); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + accept(token: string, course: string): Observable { + let url_ = this.baseUrl + "/api/{course}/invite/{token}/accept"; + if (token === undefined || token === null) + throw new globalThis.Error("The parameter 'token' must be defined."); + url_ = url_.replace("{token}", encodeURIComponent("" + token)); + if (course === undefined || course === null) + throw new globalThis.Error("The parameter 'course' must be defined."); + url_ = url_.replace("{course}", encodeURIComponent("" + course)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("post", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processAccept(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processAccept(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processAccept(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as InviteState; + return _observableOf(result200); + })); + } else if (status === 401) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result401: any = null; + result401 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result401); + })); + } else if (status === 502) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("A server side error occurred.", status, _responseText, _headers); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } +} + +export interface IAssignmentsClient { + list(course: string, includeArchived?: boolean | undefined): Observable; + create(request: SaveAssignmentRequest, course: string): Observable; + get(id: number, course: string, checkTemplate?: boolean | undefined): Observable; + update(id: number, request: SaveAssignmentRequest, course: string): Observable; + delete(id: number, course: string): Observable; + archive(id: number, course: string): Observable; + unarchive(id: number, course: string): Observable; + regenerateInvite(id: number, course: string): Observable; + listAcceptances(id: number, course: string): Observable; +} + +@Injectable({ + providedIn: 'root' +}) +export class AssignmentsClient implements IAssignmentsClient { + private http: HttpClient; + private baseUrl: string; + protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; + + constructor(@Inject(HttpClient) http: HttpClient, @Optional() @Inject(API_BASE_URL) baseUrl?: string) { + this.http = http; + this.baseUrl = baseUrl ?? "https://localhost:7443"; + } + + list(course: string, includeArchived?: boolean | undefined): Observable { + let url_ = this.baseUrl + "/api/{course}/assignments?"; + if (course === undefined || course === null) + throw new globalThis.Error("The parameter 'course' must be defined."); + url_ = url_.replace("{course}", encodeURIComponent("" + course)); + if (includeArchived === null) + throw new globalThis.Error("The parameter 'includeArchived' cannot be null."); + else if (includeArchived !== undefined) + url_ += "includeArchived=" + encodeURIComponent("" + includeArchived) + "&"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processList(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processList(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processList(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as AssignmentDto[]; + return _observableOf(result200); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + create(request: SaveAssignmentRequest, course: string): Observable { + let url_ = this.baseUrl + "/api/{course}/assignments"; + if (course === undefined || course === null) + throw new globalThis.Error("The parameter 'course' must be defined."); + url_ = url_.replace("{course}", encodeURIComponent("" + course)); + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(request); + + let options_ : any = { + body: content_, + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Content-Type": "application/json", + "Accept": "application/json" + }) + }; + + return this.http.request("post", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processCreate(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processCreate(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processCreate(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 201) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result201: any = null; + result201 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as AssignmentDto; + return _observableOf(result201); + })); + } else if (status === 400) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result400: any = null; + result400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result400); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + get(id: number, course: string, checkTemplate?: boolean | undefined): Observable { + let url_ = this.baseUrl + "/api/{course}/assignments/{id}?"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + if (course === undefined || course === null) + throw new globalThis.Error("The parameter 'course' must be defined."); + url_ = url_.replace("{course}", encodeURIComponent("" + course)); + if (checkTemplate === null) + throw new globalThis.Error("The parameter 'checkTemplate' cannot be null."); + else if (checkTemplate !== undefined) + url_ += "checkTemplate=" + encodeURIComponent("" + checkTemplate) + "&"; + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processGet(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processGet(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processGet(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as AssignmentDetailDto; + return _observableOf(result200); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + update(id: number, request: SaveAssignmentRequest, course: string): Observable { + let url_ = this.baseUrl + "/api/{course}/assignments/{id}"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + if (course === undefined || course === null) + throw new globalThis.Error("The parameter 'course' must be defined."); + url_ = url_.replace("{course}", encodeURIComponent("" + course)); + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(request); + + let options_ : any = { + body: content_, + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Content-Type": "application/json", + "Accept": "application/json" + }) + }; + + return this.http.request("put", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processUpdate(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processUpdate(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processUpdate(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as AssignmentDto; + return _observableOf(result200); + })); + } else if (status === 400) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result400: any = null; + result400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result400); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + delete(id: number, course: string): Observable { + let url_ = this.baseUrl + "/api/{course}/assignments/{id}"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + if (course === undefined || course === null) + throw new globalThis.Error("The parameter 'course' must be defined."); + url_ = url_.replace("{course}", encodeURIComponent("" + course)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + }) + }; + + return this.http.request("delete", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processDelete(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processDelete(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processDelete(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return _observableOf(null as any); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status === 409) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result409: any = null; + result409 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result409); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + archive(id: number, course: string): Observable { + let url_ = this.baseUrl + "/api/{course}/assignments/{id}/archive"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + if (course === undefined || course === null) + throw new globalThis.Error("The parameter 'course' must be defined."); + url_ = url_.replace("{course}", encodeURIComponent("" + course)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("post", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processArchive(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processArchive(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processArchive(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as AssignmentDto; + return _observableOf(result200); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + unarchive(id: number, course: string): Observable { + let url_ = this.baseUrl + "/api/{course}/assignments/{id}/unarchive"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + if (course === undefined || course === null) + throw new globalThis.Error("The parameter 'course' must be defined."); + url_ = url_.replace("{course}", encodeURIComponent("" + course)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("post", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processUnarchive(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processUnarchive(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processUnarchive(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as AssignmentDto; + return _observableOf(result200); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + regenerateInvite(id: number, course: string): Observable { + let url_ = this.baseUrl + "/api/{course}/assignments/{id}/regenerate-invite"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + if (course === undefined || course === null) + throw new globalThis.Error("The parameter 'course' must be defined."); + url_ = url_.replace("{course}", encodeURIComponent("" + course)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("post", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processRegenerateInvite(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processRegenerateInvite(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processRegenerateInvite(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as AssignmentDto; + return _observableOf(result200); + })); + } else if (status === 404) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result404: any = null; + result404 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result404); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + + listAcceptances(id: number, course: string): Observable { + let url_ = this.baseUrl + "/api/{course}/assignments/{id}/acceptances"; + if (id === undefined || id === null) + throw new globalThis.Error("The parameter 'id' must be defined."); + url_ = url_.replace("{id}", encodeURIComponent("" + id)); + if (course === undefined || course === null) + throw new globalThis.Error("The parameter 'course' must be defined."); + url_ = url_.replace("{course}", encodeURIComponent("" + course)); + url_ = url_.replace(/[?&]$/, ""); + + let options_ : any = { + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Accept": "application/json" + }) + }; + + return this.http.request("get", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processListAcceptances(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processListAcceptances(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processListAcceptances(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as AssignmentAcceptanceDto[]; + return _observableOf(result200); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } +} + export interface IGradesClient { list(course: string): Observable; exportCsv(course: string): Observable; @@ -628,6 +1484,92 @@ export class ExternalAuthClient implements IExternalAuthClient { } } +export interface IProfileClient { + setGitHubUsername(request: SetGitHubUsernameRequest): Observable; +} + +@Injectable({ + providedIn: 'root' +}) +export class ProfileClient implements IProfileClient { + private http: HttpClient; + private baseUrl: string; + protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined; + + constructor(@Inject(HttpClient) http: HttpClient, @Optional() @Inject(API_BASE_URL) baseUrl?: string) { + this.http = http; + this.baseUrl = baseUrl ?? "https://localhost:7443"; + } + + setGitHubUsername(request: SetGitHubUsernameRequest): Observable { + let url_ = this.baseUrl + "/api/profile/github"; + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(request); + + let options_ : any = { + body: content_, + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Content-Type": "application/json", + "Accept": "application/json" + }) + }; + + return this.http.request("put", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processSetGitHubUsername(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processSetGitHubUsername(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processSetGitHubUsername(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as GitHubProfileResponse; + return _observableOf(result200); + })); + } else if (status === 400) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result400: any = null; + result400 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result400); + })); + } else if (status === 401) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result401: any = null; + result401 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails; + return throwException("A server side error occurred.", status, _responseText, _headers, result401); + })); + } else if (status === 502) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("A server side error occurred.", status, _responseText, _headers); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } +} + export interface ICourseHealthAdminClient { checkAll(): Observable; checkCourse(courseId: number): Observable; @@ -2104,6 +3046,89 @@ export class UsersAdminClient implements IUsersAdminClient { } } +export interface StudentRepository { + acceptanceId?: number; + courseSlug?: string; + courseName?: string; + assignmentName?: string; + gitHubRepoName?: string; + repoUrl?: string; + acceptedAt?: Date; + access?: RepositoryAccess; + invitationUrl?: string | undefined; + invitationSentAt?: Date | undefined; +} + +export type RepositoryAccess = "Active" | "InvitationPending" | "InvitationExpired" | "Unknown"; + +export interface ProblemDetails { + type?: string | undefined; + title?: string | undefined; + status?: number | undefined; + detail?: string | undefined; + instance?: string | undefined; + + [key: string]: any; +} + +export interface InviteState { + status?: InviteStatus; + courseName?: string; + courseSlug?: string; + assignmentName?: string; + assignmentDescription?: string | undefined; + organization?: string | undefined; + repositoryName?: string | undefined; + repoUrl?: string | undefined; + gitHubUsername?: string | undefined; + invitationUrl?: string | undefined; + message?: string | undefined; +} + +export type InviteStatus = "NotFound" | "Closed" | "NeedsNeptun" | "NeedsGitHubUsername" | "ReadyToAccept" | "Accepted" | "NotConfigured"; + +export interface AssignmentDto { + id?: number; + name?: string; + description?: string | undefined; + templateRepoName?: string; + invitePath?: string; + isArchived?: boolean; + archivedAt?: Date | undefined; + createdAt?: Date; + acceptanceCount?: number; +} + +export interface AssignmentDetailDto { + assignment?: AssignmentDto; + template?: TemplateCheckDto | undefined; +} + +export interface TemplateCheckDto { + reachable?: boolean; + isTemplate?: boolean; + htmlUrl?: string | undefined; + problem?: string | undefined; +} + +export interface SaveAssignmentRequest { + name?: string; + description?: string | undefined; + templateRepoName?: string; +} + +export interface AssignmentAcceptanceDto { + id?: number; + userName?: string; + displayName?: string | undefined; + neptunCode?: string | undefined; + gitHubUsername?: string; + gitHubRepoName?: string; + repoUrl?: string; + acceptedAt?: Date; + invitationPending?: boolean; +} + export interface FinalStudentGrade { neptun?: string; repo?: string; @@ -2136,6 +3161,8 @@ export interface CurrentUserResponse { userName?: string; email?: string | undefined; displayName?: string | undefined; + neptunCode?: string | undefined; + gitHubUsername?: string | undefined; roles?: string[]; courses?: CourseMembershipDto[]; } @@ -2162,16 +3189,6 @@ export interface LogoutResponse { endSessionUrl?: string | undefined; } -export interface ProblemDetails { - type?: string | undefined; - title?: string | undefined; - status?: number | undefined; - detail?: string | undefined; - instance?: string | undefined; - - [key: string]: any; -} - export interface RegisterRequest { userName: string; email: string; @@ -2179,6 +3196,16 @@ export interface RegisterRequest { displayName?: string | undefined; } +export interface GitHubProfileResponse { + gitHubUsername?: string; + gitHubUserId?: number | undefined; +} + +export interface SetGitHubUsernameRequest { + gitHubUsername?: string; + courseSlug?: string | undefined; +} + export interface CourseHealthReport { courseId?: number; courseSlug?: string; diff --git a/ahk-frontend/src/app/app.routes.ts b/ahk-frontend/src/app/app.routes.ts index 0482f054..ccb0dad2 100644 --- a/ahk-frontend/src/app/app.routes.ts +++ b/ahk-frontend/src/app/app.routes.ts @@ -10,11 +10,12 @@ export const routes: Routes = [ loadComponent: () => import('./features/login/login').then((m) => m.Login), }, { - // Signed in, but assigned to nothing yet. Without this the guards would bounce such a user back to the - // login screen they just came from, with no explanation. - path: 'no-access', + // A student's own repositories, across every course, and where signing in lands anyone who staffs none. + // Its empty state explains what to do next, which is why there is no separate "no access" screen: a user + // with no courses is a student who has not accepted an assignment yet, not an error. + path: 'my', canActivate: [authGuard], - loadComponent: () => import('./features/no-access/no-access').then((m) => m.NoAccess), + loadComponent: () => import('./features/my/my-assignments').then((m) => m.MyAssignments), }, { // Host/admin context (no course segment). @@ -41,6 +42,14 @@ export const routes: Routes = [ { path: '', pathMatch: 'full', redirectTo: 'courses' }, ], }, + { + // The assignment invite link. Deliberately outside the course shell and guarded only by authGuard: + // students are members of no course, and accepting is how they first appear in one at all — courseGuard + // would bounce every one of them. Declared before ':course' so the match is unambiguous. + path: ':course/invite/:token', + canActivate: [authGuard], + loadComponent: () => import('./features/invite/invite').then((m) => m.Invite), + }, { // Course context: /{course}/... path: ':course', @@ -51,6 +60,10 @@ export const routes: Routes = [ path: 'dashboard', loadComponent: () => import('./features/course/dashboard/dashboard').then((m) => m.CourseDashboard), }, + { + path: 'assignments', + loadComponent: () => import('./features/course/assignments/assignments').then((m) => m.CourseAssignments), + }, { path: '', pathMatch: 'full', redirectTo: 'dashboard' }, ], }, diff --git a/ahk-frontend/src/app/core/auth/auth.service.ts b/ahk-frontend/src/app/core/auth/auth.service.ts index 4e608d73..00c85f1a 100644 --- a/ahk-frontend/src/app/core/auth/auth.service.ts +++ b/ahk-frontend/src/app/core/auth/auth.service.ts @@ -40,6 +40,20 @@ export class AuthService { ); } + /** + * Re-fetches the session, ignoring the cache. Needed after the user changes something the session carries — + * their GitHub username, for one — so the rest of the app does not keep showing the stale value. + */ + reload(): Observable { + return this.authClient.me().pipe( + tap((u) => this.setUser(u)), + catchError(() => { + this.setLoggedOut(); + return of(null); + }), + ); + } + /** * Signs in. Resolves to null on success, or to the reason it failed — the API's own message for a bad * password or a locked-out account, and a distinct one when the backend cannot be reached at all. @@ -78,13 +92,17 @@ export class AuthService { return this.courses().some((c) => c.slug === slug); } - /** Where signing in should land: the admin console for admins, otherwise the first course they can open. */ + /** + * Where signing in should land: the admin console for admins, then the first course they staff. Everyone + * else is a student, so they go to their own repositories — which doubles as the "you have nothing yet" + * screen and tells them to ask for an invite link. + */ landingUrl(): string { if (this.isAdmin()) { return '/admin/courses'; } const first = this.courses()[0]; - return first ? `/${first.slug}/dashboard` : '/no-access'; + return first ? `/${first.slug}/dashboard` : '/my'; } private setUser(u: CurrentUserResponse): void { diff --git a/ahk-frontend/src/app/core/clipboard.ts b/ahk-frontend/src/app/core/clipboard.ts new file mode 100644 index 00000000..8641e9b6 --- /dev/null +++ b/ahk-frontend/src/app/core/clipboard.ts @@ -0,0 +1,35 @@ +/** + * Copies text to the clipboard, resolving to whether it worked. + * + * The async Clipboard API is the path that runs — the app is HTTPS in development and production alike — but it + * is also refused outright when the document is not focused or the browser withholds permission, and an invite + * link the instructor believes they copied is worse than one they know they did not. The textarea fallback + * covers those cases; the caller uses the result to decide what to say. + */ +export async function copyToClipboard(text: string): Promise { + if (navigator.clipboard?.writeText) { + try { + await navigator.clipboard.writeText(text); + return true; + } catch { + // Permission refused or the document is not focused — fall through. + } + } + + const area = document.createElement('textarea'); + area.value = text; + + // Off-screen rather than hidden: an element with display:none cannot be selected. + area.style.position = 'fixed'; + area.style.left = '-9999px'; + document.body.appendChild(area); + + try { + area.select(); + return document.execCommand('copy'); + } catch { + return false; + } finally { + area.remove(); + } +} diff --git a/ahk-frontend/src/app/features/course/assignments/assignments.html b/ahk-frontend/src/app/features/course/assignments/assignments.html new file mode 100644 index 00000000..d125303e --- /dev/null +++ b/ahk-frontend/src/app/features/course/assignments/assignments.html @@ -0,0 +1,248 @@ +
+
+
+ Course +

Assignments

+

+ Each assignment is a template repository plus a link. Share the link with your students and they get + their own private copy, named after their Neptun code, with write access. +

+
+
+ + +
+
+ + @if (error(); as e) { +

{{ e }}

+ } + @if (saved(); as s) { +

{{ s }}

+ } + + @if (creating() || editingId() !== null) { +
+
+
+

{{ editingId() === null ? 'Add assignment' : 'Edit assignment' }}

+

+ The template repository must live in this course's organization and be marked as a template on + GitHub. +

+
+
+ +
+
+
+
+ + + Shown to students on the accept screen. +
+
+ + + + A bare name is taken to be in this course's organization. Student repositories are named + <this>-<neptun>. + +
+
+ +
+ + + Optional. Shown under the assignment name on the accept screen. +
+ + + @if (editingId() !== null) { +
+ +
+ + @if (template(); as t) { + @if (t.problem) { +

{{ t.problem }}

+ } @else { +

+ The template is reachable and marked as a template repository. + @if (t.htmlUrl) { + Open it on GitHub + } +

+ } + } + } +
+ +
+ + +
+
+
+ } + + @if (loading()) { +

Loading assignments…

+ } @else if (assignments().length === 0) { +
+

+ No assignments yet. Add one against a template repository, then share its invite link with your + students. +

+
+ } @else { + @for (a of assignments(); track a.id) { +
+
+
+

+ {{ a.name }} + @if (a.isArchived) { + Archived + } +

+

{{ a.templateRepoName }}

+
+
+ +
+ @if (a.description) { +

{{ a.description }}

+ } + + @if (a.isArchived) { +

+ This assignment no longer accepts new students. The ones who already accepted keep their + repositories and their link. +

+ } + + +
+ +
+ + +
+ + Anyone signed in who has this link can create their repository, so treat it as the key to the + assignment. Reissuing it retires the old one. + +
+ +

+ Created {{ a.createdAt | date: 'yyyy-MM-dd' }} · + +

+ + @if (expandedId() === a.id) { + @if (loadingAcceptances()) { +

Loading…

+ } @else { +
+ + + + + + + + + + + + + @for (acceptance of acceptances(); track acceptance.id) { + + + + + + + + + } @empty { + + + + } + +
StudentNeptunGitHubRepositoryAcceptedAccess
{{ acceptance.displayName || acceptance.userName }}{{ acceptance.neptunCode || '—' }}{{ acceptance.gitHubUsername }} + {{ + acceptance.gitHubRepoName + }} + {{ acceptance.acceptedAt | date: 'yyyy-MM-dd HH:mm' }} + @if (acceptance.invitationPending) { + Invitation waiting + } @else { + Ready + } +
Nobody has accepted this assignment yet.
+
+ } + } +
+ +
+ + + @if (a.isArchived) { + + } @else { + + } + + + + + @if (a.acceptanceCount === 0) { + + } +
+
+ } + } +
diff --git a/ahk-frontend/src/app/features/course/assignments/assignments.scss b/ahk-frontend/src/app/features/course/assignments/assignments.scss new file mode 100644 index 00000000..293f74c4 --- /dev/null +++ b/ahk-frontend/src/app/features/course/assignments/assignments.scss @@ -0,0 +1,82 @@ +.card + .card { + margin-top: 1.25rem; +} + +h2 { + display: flex; + align-items: center; + gap: 0.625rem; + font-size: 1.125rem; +} + +/* An archived assignment stays legible but visibly steps back — it is history, not a current handout. */ +.assignment.archived { + header h2, + .card-body { + opacity: 0.72; + } +} + +/* The invite link block: the one thing an instructor comes to this screen to get. */ +.invite { + margin-top: 1rem; + + > label { + display: block; + margin-bottom: 0.375rem; + font-family: var(--font-ui); + font-size: 0.6875rem; + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--ink-2); + } + + .hint { + display: block; + margin-top: 0.375rem; + font-family: var(--font-ui); + font-size: 0.6875rem; + color: var(--ink-2); + } +} + +.invite-row { + display: flex; + gap: 0.5rem; + + input { + flex: 1 1 auto; + min-width: 0; + font-size: 0.8125rem; + } + + .btn { + flex: none; + min-width: 5.5rem; + justify-content: center; + } +} + +.meta { + margin: 1rem 0 0; + font-size: 0.75rem; +} + +/* Prose-weight toggle for the acceptance list — a button here would compete with the card's real actions. */ +.linkish { + border: 0; + background: none; + padding: 0; + font: inherit; + color: var(--link); + cursor: pointer; + text-decoration: underline; + + &:hover { + color: var(--link-hover); + } +} + +.table-wrap { + margin-top: 0.875rem; +} diff --git a/ahk-frontend/src/app/features/course/assignments/assignments.ts b/ahk-frontend/src/app/features/course/assignments/assignments.ts new file mode 100644 index 00000000..4b34815e --- /dev/null +++ b/ahk-frontend/src/app/features/course/assignments/assignments.ts @@ -0,0 +1,260 @@ +import { DatePipe } from '@angular/common'; +import { Component, OnInit, inject, signal } from '@angular/core'; +import { FormsModule } from '@angular/forms'; + +import { + AssignmentAcceptanceDto, + AssignmentDto, + AssignmentsClient, + SaveAssignmentRequest, + TemplateCheckDto, +} from '../../../api/api-client'; +import { readApiError } from '../../../core/api-error'; +import { copyToClipboard } from '../../../core/clipboard'; +import { CourseContextService } from '../../../core/course/course-context.service'; + +/** + * Assignment administration for a course — what used to be set up in GitHub Classroom. + * + * The invite link is the point of this screen, so copying it is a first-class action rather than something + * the instructor has to select out of a table cell. + */ +@Component({ + selector: 'app-course-assignments', + imports: [FormsModule, DatePipe], + templateUrl: './assignments.html', + styleUrl: './assignments.scss', +}) +export class CourseAssignments implements OnInit { + private readonly client = inject(AssignmentsClient); + private readonly courseContext = inject(CourseContextService); + + protected readonly assignments = signal([]); + protected readonly loading = signal(true); + protected readonly error = signal(null); + protected readonly saved = signal(null); + protected readonly showArchived = signal(false); + + /** Which invite link was copied last, so only that row shows the confirmation. */ + protected readonly copiedId = signal(null); + + // ---- Editor ---- + protected readonly editingId = signal(null); + protected readonly creating = signal(false); + protected readonly savingForm = signal(false); + protected name = ''; + protected description = ''; + protected templateRepoName = ''; + + /** Advisory check of the template repository; costs a GitHub call, so it is only run on demand. */ + protected readonly template = signal(null); + protected readonly checkingTemplate = signal(false); + + // ---- Acceptance roster ---- + protected readonly expandedId = signal(null); + protected readonly acceptances = signal([]); + protected readonly loadingAcceptances = signal(false); + + private get course(): string { + return this.courseContext.activeSlug() ?? ''; + } + + ngOnInit(): void { + this.load(); + } + + protected load(): void { + this.loading.set(true); + this.client.list(this.course, this.showArchived()).subscribe({ + next: (assignments) => { + this.assignments.set(assignments); + this.loading.set(false); + }, + error: (err: unknown) => { + this.error.set(readApiError(err, 'The assignments could not be loaded.')); + this.loading.set(false); + }, + }); + } + + protected toggleArchived(): void { + this.showArchived.update((v) => !v); + this.load(); + } + + // ---- Editor ---- + + protected startCreate(): void { + this.clearMessages(); + this.creating.set(true); + this.editingId.set(null); + this.template.set(null); + this.name = ''; + this.description = ''; + this.templateRepoName = ''; + } + + protected startEdit(assignment: AssignmentDto): void { + this.clearMessages(); + this.creating.set(false); + this.editingId.set(assignment.id ?? null); + this.template.set(null); + this.name = assignment.name ?? ''; + this.description = assignment.description ?? ''; + this.templateRepoName = assignment.templateRepoName ?? ''; + } + + protected cancelEdit(): void { + this.creating.set(false); + this.editingId.set(null); + this.template.set(null); + } + + protected save(): void { + this.clearMessages(); + this.savingForm.set(true); + + const request: SaveAssignmentRequest = { + name: this.name.trim(), + description: this.description.trim() || undefined, + templateRepoName: this.templateRepoName.trim(), + }; + + const id = this.editingId(); + const call = id === null ? this.client.create(request, this.course) : this.client.update(id, request, this.course); + + call.subscribe({ + next: (assignment) => { + this.savingForm.set(false); + this.saved.set( + id === null + ? `"${assignment.name}" was created. Copy its invite link and share it with your students.` + : `"${assignment.name}" was saved.`, + ); + this.cancelEdit(); + this.load(); + }, + error: (err: unknown) => { + this.savingForm.set(false); + this.error.set(readApiError(err, 'The assignment could not be saved.')); + }, + }); + } + + /** + * Asks GitHub whether the template repository exists and is marked as a template. Advisory only — an + * assignment may legitimately be drafted before its template does. + */ + protected checkTemplate(): void { + const id = this.editingId(); + if (id === null) { + return; + } + + this.checkingTemplate.set(true); + this.client.get(id, this.course, true).subscribe({ + next: (detail) => { + this.template.set(detail.template ?? null); + this.checkingTemplate.set(false); + }, + error: () => this.checkingTemplate.set(false), + }); + } + + // ---- Invite link ---- + + /** + * The API returns the invite link as a path, not an absolute URL — behind the dev proxy it would otherwise + * be built from a rewritten Host header and point at the backend's port. The browser's own origin is by + * definition the one the student will use. + */ + protected inviteUrl(assignment: AssignmentDto): string { + return `${window.location.origin}${assignment.invitePath ?? ''}`; + } + + protected async copyInvite(assignment: AssignmentDto): Promise { + this.clearMessages(); + + const copied = await copyToClipboard(this.inviteUrl(assignment)); + if (copied) { + this.copiedId.set(assignment.id ?? null); + setTimeout(() => this.copiedId.set(null), 2500); + } else { + this.error.set('The link could not be copied automatically — select it and copy it by hand.'); + } + } + + /** Retires the current link. Anyone holding the old one gets "this invite link does not match an assignment". */ + protected regenerateInvite(assignment: AssignmentDto): void { + this.clearMessages(); + this.client.regenerateInvite(assignment.id ?? 0, this.course).subscribe({ + next: () => { + this.saved.set( + `"${assignment.name}" has a new invite link. The previous one no longer works — share the new one.`, + ); + this.load(); + }, + error: (err: unknown) => this.error.set(readApiError(err, 'A new invite link could not be issued.')), + }); + } + + // ---- Lifecycle ---- + + protected setArchived(assignment: AssignmentDto, archived: boolean): void { + this.clearMessages(); + + const id = assignment.id ?? 0; + const call = archived ? this.client.archive(id, this.course) : this.client.unarchive(id, this.course); + + call.subscribe({ + next: () => { + this.saved.set( + archived + ? `"${assignment.name}" was archived. Its invite link no longer accepts new students; the ones who already accepted keep their repositories.` + : `"${assignment.name}" was reopened and accepts students again.`, + ); + this.load(); + }, + error: (err: unknown) => this.error.set(readApiError(err, 'That could not be changed.')), + }); + } + + protected remove(assignment: AssignmentDto): void { + this.clearMessages(); + this.client.delete(assignment.id ?? 0, this.course).subscribe({ + next: () => { + this.saved.set(`"${assignment.name}" was deleted.`); + this.load(); + }, + error: (err: unknown) => this.error.set(readApiError(err, 'That assignment could not be deleted.')), + }); + } + + // ---- Acceptances ---- + + protected toggleAcceptances(assignment: AssignmentDto): void { + const id = assignment.id ?? 0; + + if (this.expandedId() === id) { + this.expandedId.set(null); + return; + } + + this.expandedId.set(id); + this.acceptances.set([]); + this.loadingAcceptances.set(true); + + this.client.listAcceptances(id, this.course).subscribe({ + next: (acceptances) => { + this.acceptances.set(acceptances); + this.loadingAcceptances.set(false); + }, + error: () => this.loadingAcceptances.set(false), + }); + } + + private clearMessages(): void { + this.error.set(null); + this.saved.set(null); + } +} diff --git a/ahk-frontend/src/app/features/invite/invite.html b/ahk-frontend/src/app/features/invite/invite.html new file mode 100644 index 00000000..5f06c2ac --- /dev/null +++ b/ahk-frontend/src/app/features/invite/invite.html @@ -0,0 +1,182 @@ +
+
+ +

AHK — Automated homework evaluation

+
+ + @if (loading()) { +
+
+

Opening the invitation…

+
+
+ } @else if (state(); as s) { +
+
+
+ {{ s.courseName }} +

{{ s.assignmentName }}

+
+
+ +
+ @switch (s.status) { + + @case ('ReadyToAccept') { +

Accept the assignment — {{ s.assignmentName }}

+ + @if (s.assignmentDescription) { +

{{ s.assignmentDescription }}

+ } + +

+ Once you accept this assignment, you will be granted access to the + {{ s.repositoryName }} + repository in the + {{ s.organization }} + organization on GitHub. +

+ +

+ It will be shared with your GitHub account, + {{ s.gitHubUsername }}. +

+ + @if (error(); as e) { +

{{ e }}

+ } + +
+ +
+ } + + @case ('Accepted') { +

You're ready to go!

+

You accepted the assignment, {{ s.assignmentName }}

+ + @if (s.invitationUrl) { + +

+ GitHub has invited you to your repository. Accept the invitation and the repository is + yours — the link below takes you straight to it. +

+

{{ s.repositoryName }}

+ +
+ +
+ } @else { +

Your assignment repository has been created:

+

+ {{ s.repoUrl }} +

+

We've configured the repository associated with this assignment.

+ + @if (s.message) { +

{{ s.message }}

+ } + +
+ + + @if (redirectingIn(); as seconds) { + + } +
+ } + } + + + @case ('NeedsGitHubUsername') { +

First, tell us your GitHub username

+

+ This site works by giving you your own repository on GitHub, so it needs to know which + account is yours. We check the name against GitHub before saving it, and you will only be + asked this once. +

+ +
+
+ + + + The name in your profile URL — github.com/username. Not your email + address. + +
+ + @if (error(); as e) { +

{{ e }}

+ } + +
+ +
+
+ } + + + @case ('NeedsNeptun') { +

{{ s.message }}

+

+ Repositories are named after your Neptun code, which comes from your university account. Sign + out and sign back in with eduID, and this page will work. +

+ } + + @case ('Closed') { +

{{ s.message }}

+

+ If you think you should still be able to accept it, ask your instructor — they can reopen the + assignment. +

+ } + + @case ('NotConfigured') { +

{{ s.message }}

+ } + + @default { +

+ {{ s.message || 'This invite link does not match an assignment.' }} +

+

Ask your instructor for a current link — invite links can be reissued, which retires the old one.

+ } + } +
+
+ } @else { +
+
+

{{ error() || 'This invite link could not be opened.' }}

+
+
+ } +
diff --git a/ahk-frontend/src/app/features/invite/invite.scss b/ahk-frontend/src/app/features/invite/invite.scss new file mode 100644 index 00000000..932848cc --- /dev/null +++ b/ahk-frontend/src/app/features/invite/invite.scss @@ -0,0 +1,56 @@ +/* Same standalone, centred frame as the login screen: a student following an invite link has no course + context yet, so there is no rail and no switcher to sit inside. */ +.invite { + max-width: 32rem; + margin: 0 auto; + padding: 3rem 1.25rem 4rem; +} + +.mark { + display: flex; + flex-direction: column; + gap: 0.875rem; + margin-bottom: 1.5rem; + + .logo { + display: block; + width: 100%; + max-width: 17rem; + height: auto; + } +} + +.product { + font-size: 1rem; +} + +h2 { + font-size: 1.25rem; +} + +.lede { + font-size: 0.9375rem; +} + +/* The repository is the thing the student came for — give it room and set it in the machine face. */ +.repo { + margin: 0.75rem 0; + padding: 0.625rem 0.75rem; + border: 1px solid var(--rule); + border-radius: var(--radius); + background: var(--paper); + font-size: 0.8125rem; + overflow-wrap: anywhere; + + a { + color: var(--link); + + &:hover { + color: var(--link-hover); + } + } +} + +.btn-row { + margin-top: 1.25rem; +} diff --git a/ahk-frontend/src/app/features/invite/invite.ts b/ahk-frontend/src/app/features/invite/invite.ts new file mode 100644 index 00000000..f444e917 --- /dev/null +++ b/ahk-frontend/src/app/features/invite/invite.ts @@ -0,0 +1,148 @@ +import { Component, OnDestroy, OnInit, inject, signal } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { ActivatedRoute } from '@angular/router'; + +import { AssignmentInviteClient, InviteState, ProfileClient } from '../../api/api-client'; +import { readApiError } from '../../core/api-error'; +import { AuthService } from '../../core/auth/auth.service'; + +/** + * What a student sees when they follow an assignment's invite link — the replacement for GitHub Classroom's + * accept page. + * + * One component for the whole flow, driven entirely by the `status` the API returns rather than by local + * step-counting: the server decides what is still missing, and re-decides it on accept, so a reload or a + * back-button never lands the student in a state the server disagrees with. + */ +@Component({ + selector: 'app-invite', + imports: [FormsModule], + templateUrl: './invite.html', + styleUrl: './invite.scss', +}) +export class Invite implements OnInit, OnDestroy { + private readonly inviteClient = inject(AssignmentInviteClient); + private readonly profileClient = inject(ProfileClient); + private readonly auth = inject(AuthService); + private readonly route = inject(ActivatedRoute); + + protected readonly state = signal(null); + protected readonly loading = signal(true); + protected readonly accepting = signal(false); + protected readonly error = signal(null); + + /** Counts down the redirect to GitHub, so the confirmation is readable before the page moves on. */ + protected readonly redirectingIn = signal(null); + + protected gitHubUsername = ''; + protected readonly savingUsername = signal(false); + + private course = ''; + private token = ''; + private redirectTimer?: ReturnType; + + ngOnInit(): void { + this.course = this.route.snapshot.paramMap.get('course') ?? ''; + this.token = this.route.snapshot.paramMap.get('token') ?? ''; + this.load(); + } + + ngOnDestroy(): void { + this.clearRedirect(); + } + + private load(): void { + this.loading.set(true); + this.inviteClient.get(this.token, this.course).subscribe({ + next: (state) => { + this.state.set(state); + this.loading.set(false); + }, + error: (err: unknown) => { + this.error.set(readApiError(err, 'This invite link could not be opened.')); + this.loading.set(false); + }, + }); + } + + /** Verified server-side against the GitHub API, so a typo comes back as a message rather than a broken repo. */ + protected saveGitHubUsername(): void { + const login = this.gitHubUsername.trim(); + if (!login) { + return; + } + + this.error.set(null); + this.savingUsername.set(true); + + this.profileClient.setGitHubUsername({ gitHubUsername: login, courseSlug: this.course }).subscribe({ + next: () => { + this.savingUsername.set(false); + this.gitHubUsername = ''; + + // The session carries the username too, and the student may go to /my straight afterwards. + this.auth.reload().subscribe(); + this.load(); + }, + error: (err: unknown) => { + this.savingUsername.set(false); + this.error.set(readApiError(err, 'That username could not be checked. Try again in a moment.')); + }, + }); + } + + protected accept(): void { + this.error.set(null); + this.accepting.set(true); + + this.inviteClient.accept(this.token, this.course).subscribe({ + next: (state) => { + this.accepting.set(false); + this.state.set(state); + + // Only send them onward when the repository is actually open to them. With an invitation still + // outstanding the repository 404s, so the page keeps them here and points at the invitation instead. + if (state.status === 'Accepted' && state.repoUrl && !state.invitationUrl) { + this.startRedirect(state.repoUrl); + } + }, + error: (err: unknown) => { + this.accepting.set(false); + this.error.set(readApiError(err, 'The repository could not be set up. Tell your instructor.')); + }, + }); + } + + protected openRepository(): void { + const url = this.state()?.invitationUrl ?? this.state()?.repoUrl; + if (url) { + this.clearRedirect(); + window.location.href = url; + } + } + + protected cancelRedirect(): void { + this.clearRedirect(); + } + + private startRedirect(url: string): void { + this.redirectingIn.set(4); + this.redirectTimer = setInterval(() => { + const left = (this.redirectingIn() ?? 0) - 1; + if (left <= 0) { + this.clearRedirect(); + window.location.href = url; + return; + } + this.redirectingIn.set(left); + }, 1000); + } + + private clearRedirect(): void { + if (this.redirectTimer) { + clearInterval(this.redirectTimer); + this.redirectTimer = undefined; + } + this.redirectingIn.set(null); + } +} diff --git a/ahk-frontend/src/app/features/my/my-assignments.html b/ahk-frontend/src/app/features/my/my-assignments.html new file mode 100644 index 00000000..b67472ce --- /dev/null +++ b/ahk-frontend/src/app/features/my/my-assignments.html @@ -0,0 +1,124 @@ +
+
+ + + @if (user(); as u) { + {{ u.displayName || u.userName }} + } + +
+ +
+
+ Your work +

Assignments

+
+
+ + @if (error(); as e) { +

{{ e }}

+ } + @if (note(); as n) { +

{{ n }}

+ } + + @if (loading()) { +

Loading your repositories…

+ } @else if (groups().length === 0) { +
+
+

Nothing here yet

+

+ You have not accepted any assignments. Your instructor hands out an invite link for each one — + follow it and your repository is created here. +

+ @if (user(); as u) { + @if (!u.gitHubUsername) { +

+ You have not told us your GitHub username yet either. The first invite link you open will ask + for it. +

+ } + } +
+
+ } @else { + @for (group of groups(); track group.slug) { +
+
+
+ {{ group.slug }} +

{{ group.name }}

+
+
+ +
+ @for (repository of group.repositories; track repository.acceptanceId) { +
+
+

{{ repository.assignmentName }}

+ + @switch (repository.access) { + @case ('Active') { + Ready + } + @case ('InvitationPending') { + Invitation waiting + } + @case ('InvitationExpired') { + Invitation expired + } + @default { + Unknown + } + } +
+ +

+ {{ + repository.gitHubRepoName + }} +

+ +

Accepted {{ repository.acceptedAt | date: 'medium' }}

+ + + @if (repository.access !== 'Active') { +

+ @if (repository.access === 'InvitationExpired') { + Your GitHub invitation ran out before you accepted it. Send a new one and open it from + GitHub. + } @else { + GitHub has invited you to this repository. Until you accept the invitation, the + repository will not open for you. + } +

+ +
+ @if (repository.invitationUrl) { + + Open the invitation + + } + +
+ } +
+ } +
+
+ } + } +
diff --git a/ahk-frontend/src/app/features/my/my-assignments.scss b/ahk-frontend/src/app/features/my/my-assignments.scss new file mode 100644 index 00000000..9ed652a4 --- /dev/null +++ b/ahk-frontend/src/app/features/my/my-assignments.scss @@ -0,0 +1,89 @@ +/* Standalone page like the invite screen: a student is a member of no course, so the shell's course rail and + switcher would have nothing to put in them. */ +.my { + max-width: 48rem; + margin: 0 auto; + padding: 1.5rem 1.25rem 4rem; +} + +.topline { + display: flex; + align-items: center; + gap: 0.75rem; + padding-bottom: 1rem; + margin-bottom: 1.5rem; + border-bottom: 1px solid var(--rule); + + .logo { + height: 1.75rem; + width: auto; + } + + .spacer { + flex: 1; + } + + .who { + font-size: 0.75rem; + color: var(--ink-2); + } +} + +h1 { + font-size: 1.5rem; +} + +h2 { + font-size: 1.125rem; +} + +h3 { + margin: 0; + font-size: 1rem; +} + +.card + .card { + margin-top: 1.25rem; +} + +/* Repositories stack inside a course card, separated by a rule rather than nested cards — the course is the + container, and a card inside a card reads as a different kind of thing. */ +.repo + .repo { + margin-top: 1.25rem; + padding-top: 1.25rem; + border-top: 1px solid var(--rule); +} + +.repo-head { + display: flex; + align-items: center; + gap: 0.625rem; + margin-bottom: 0.5rem; +} + +.path { + margin: 0 0 0.25rem; + font-size: 0.8125rem; + overflow-wrap: anywhere; + + a { + color: var(--link); + + &:hover { + color: var(--link-hover); + } + } +} + +.meta { + margin: 0; + font-size: 0.75rem; +} + +.notice { + margin-top: 0.75rem; +} + +.btn-row { + margin-top: 0.75rem; +} diff --git a/ahk-frontend/src/app/features/my/my-assignments.ts b/ahk-frontend/src/app/features/my/my-assignments.ts new file mode 100644 index 00000000..a47e1f00 --- /dev/null +++ b/ahk-frontend/src/app/features/my/my-assignments.ts @@ -0,0 +1,103 @@ +import { DatePipe } from '@angular/common'; +import { Component, OnInit, computed, inject, signal } from '@angular/core'; + +import { MyAssignmentsClient, StudentRepository } from '../../api/api-client'; +import { readApiError } from '../../core/api-error'; +import { AuthService } from '../../core/auth/auth.service'; + +/** One course's worth of repositories, which is how the page is grouped. */ +interface CourseGroup { + slug: string; + name: string; + repositories: StudentRepository[]; +} + +/** + * A student's own page: every repository they hold, across every course. + * + * This is also where a student lands when they sign in without an invite link, so it doubles as the + * "you have nothing yet" screen — the empty state has to explain what to do, not just report a void. + */ +@Component({ + selector: 'app-my-assignments', + imports: [DatePipe], + templateUrl: './my-assignments.html', + styleUrl: './my-assignments.scss', +}) +export class MyAssignments implements OnInit { + private readonly client = inject(MyAssignmentsClient); + private readonly auth = inject(AuthService); + + protected readonly repositories = signal([]); + protected readonly loading = signal(true); + protected readonly error = signal(null); + protected readonly resending = signal(null); + protected readonly note = signal(null); + + protected readonly user = this.auth.currentUser; + + /** Grouped by course, preserving the API's newest-first order within each. */ + protected readonly groups = computed(() => { + const byCourse = new Map(); + + for (const repository of this.repositories()) { + const slug = repository.courseSlug ?? ''; + const group = byCourse.get(slug) ?? { slug, name: repository.courseName ?? slug, repositories: [] }; + group.repositories.push(repository); + byCourse.set(slug, group); + } + + return [...byCourse.values()]; + }); + + ngOnInit(): void { + this.load(); + } + + protected load(): void { + this.loading.set(true); + this.client.list().subscribe({ + next: (repositories) => { + this.repositories.set(repositories); + this.loading.set(false); + }, + error: (err: unknown) => { + this.error.set(readApiError(err, 'Your assignments could not be loaded.')); + this.loading.set(false); + }, + }); + } + + /** + * GitHub cannot extend an invitation, so this withdraws the stale one and issues a fresh one. The student + * still has to click through it on GitHub — the button only puts a live invitation back in their inbox. + */ + protected resend(repository: StudentRepository): void { + const id = repository.acceptanceId ?? 0; + + this.error.set(null); + this.note.set(null); + this.resending.set(id); + + this.client.resendInvitation(id).subscribe({ + next: (updated) => { + this.resending.set(null); + this.repositories.update((list) => list.map((r) => (r.acceptanceId === id ? updated : r))); + + this.note.set( + updated.access === 'Active' + ? 'You already have access to that repository — no invitation was needed.' + : 'A new invitation is on its way. Open it from the link next to the repository, or from your GitHub notifications.', + ); + }, + error: (err: unknown) => { + this.resending.set(null); + this.error.set(readApiError(err, 'The invitation could not be sent. Try again in a few minutes.')); + }, + }); + } + + protected logout(): void { + this.auth.logout().subscribe(); + } +} diff --git a/ahk-frontend/src/app/features/no-access/no-access.html b/ahk-frontend/src/app/features/no-access/no-access.html deleted file mode 100644 index e04727c3..00000000 --- a/ahk-frontend/src/app/features/no-access/no-access.html +++ /dev/null @@ -1,14 +0,0 @@ -
- Signed in -

You are not assigned to a course

-

- Your account works, but no course has been assigned to it yet, so there is nothing to show. Ask the - administrator of your course to add - {{ user()?.userName }} - as staff. -

- -
- -
-
diff --git a/ahk-frontend/src/app/features/no-access/no-access.scss b/ahk-frontend/src/app/features/no-access/no-access.scss deleted file mode 100644 index 2c7fd9cc..00000000 --- a/ahk-frontend/src/app/features/no-access/no-access.scss +++ /dev/null @@ -1,13 +0,0 @@ -.no-access { - max-width: 34rem; - margin: 0 auto; - padding: 5rem 1.25rem; -} - -h1 { - margin-bottom: 0.5rem; -} - -.lede { - margin-bottom: 1.5rem; -} diff --git a/ahk-frontend/src/app/features/no-access/no-access.ts b/ahk-frontend/src/app/features/no-access/no-access.ts deleted file mode 100644 index a8457365..00000000 --- a/ahk-frontend/src/app/features/no-access/no-access.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Component, inject } from '@angular/core'; -import { Router } from '@angular/router'; - -import { AuthService } from '../../core/auth/auth.service'; - -/** Landing for a signed-in user who is not assigned to any course yet, so the guards have nowhere to send them. */ -@Component({ - selector: 'app-no-access', - templateUrl: './no-access.html', - styleUrl: './no-access.scss', -}) -export class NoAccess { - private readonly auth = inject(AuthService); - private readonly router = inject(Router); - - protected readonly user = this.auth.currentUser; - - protected logout(): void { - this.auth.logout().subscribe(() => this.router.navigate(['/login'])); - } -} diff --git a/ahk-frontend/src/app/layout/shell/shell.html b/ahk-frontend/src/app/layout/shell/shell.html index b6232cbe..0a0e853f 100644 --- a/ahk-frontend/src/app/layout/shell/shell.html +++ b/ahk-frontend/src/app/layout/shell/shell.html @@ -48,6 +48,7 @@ } @else { {{ activeCourse()?.name || activeSlug() }} Submissions + Assignments @if (activeCourse(); as course) { @if (course.viaSiteAdmin) { From 6356ab5eba7d8a8264a9bf361343b23d34c9a143 Mon Sep 17 00:00:00 2001 From: Bence Kovari Date: Sat, 25 Jul 2026 18:36:41 +0200 Subject: [PATCH 04/19] feat: update VPN configuration and routing in deployment workflow --- .claude/settings.json | 3 +- .github/workflows/ahk-web-deploy.yaml | 42 +++++++++++++++++---------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/.claude/settings.json b/.claude/settings.json index 9c607d4c..0fb50beb 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -76,7 +76,8 @@ "PowerShell(Get-NetTCPConnection -LocalPort 7443,4200 -State Listen -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -ErrorAction SilentlyContinue }; Start-Sleep -Milliseconds 500; if \\($null -eq \\(Get-NetTCPConnection -LocalPort 7443,4200 -State Listen -ErrorAction SilentlyContinue\\)\\) { \"both ports free\" })", "Bash(grep -nE \"^[0-9.]+ [0-9.]+ [0-9.]+ [0-9.]+ \\(k|K\\)$\")", "Bash(sort -u -t: -k2)", - "Bash(python3 -)" + "Bash(python3 -)", + "Bash(python -c \"import yaml,sys; yaml.safe_load\\(open\\('.github/workflows/ahk-web-deploy.yaml'\\)\\); print\\('YAML OK'\\)\")" ], "additionalDirectories": [ "\\tmp" diff --git a/.github/workflows/ahk-web-deploy.yaml b/.github/workflows/ahk-web-deploy.yaml index 48eba0ea..05d67feb 100644 --- a/.github/workflows/ahk-web-deploy.yaml +++ b/.github/workflows/ahk-web-deploy.yaml @@ -102,24 +102,19 @@ jobs: id: vpn env: VPN_ADDRESS: ${{ vars.VPN_ADDRESS }} - VPN_USER: ${{ secrets.VPN_USER }} + VPN_USER: ${{ vars.VPN_USER }} VPN_PASSWORD: ${{ secrets.VPN_PASSWORD }} - # Optional: PEM of the CA that signed the VPN server cert (or the self-signed cert itself). - # Set this if the endpoint does not present a publicly-trusted certificate. When unset, sstpc - # validates against the system CA store. Never use --cert-warn: that downgrades a failed - # server-certificate check to a warning and lets a MITM harvest these credentials. - VPN_CA_CERT: ${{ secrets.VPN_CA_CERT }} run: | - CERT_ARGS=() - if [ -n "$VPN_CA_CERT" ]; then - echo "$VPN_CA_CERT" > /tmp/vpn-ca.crt - CERT_ARGS=(--ca-cert /tmp/vpn-ca.crt) - fi - sudo sstpc --log-stderr "${CERT_ARGS[@]}" \ + # sstpc is a daemon that never returns. Background it AND redirect its stdout/stderr to a + # logfile: otherwise the backgrounded process keeps this step's output pipe open and the step + # hangs forever despite the '&'. No --cert-warn — the endpoint's cert validates against the + # system CA store. No 'defaultroute' — it is inert here (the runner's eth0 default wins), which + # is why internal traffic was not tunneled; the explicit host route in the next step handles it. + sudo sstpc --log-stderr \ --user "$VPN_USER" --password "$VPN_PASSWORD" \ "$VPN_ADDRESS" \ - usepeerdns require-mschap-v2 noauth noipdefault defaultroute refuse-eap \ - unit 0 & + usepeerdns require-mschap-v2 noauth noipdefault refuse-eap \ + unit 0 > /tmp/sstpc.log 2>&1 & # Wait (up to ~60s) for the ppp0 interface to acquire an address. for i in $(seq 1 30); do if ip -4 addr show ppp0 2>/dev/null | grep -q 'inet '; then @@ -129,19 +124,34 @@ jobs: sleep 2 done echo "::error::SSTP VPN did not come up within timeout" + cat /tmp/sstpc.log || true exit 1 + - name: Route BME-internal hosts through the tunnel + env: + VPN_ROUTES: ${{ vars.VPN_ROUTES }} + run: | + # Split tunnel: only the configured internal hosts (e.g. mezga 152.66.188.8/32) go through + # ppp0. The runner->GitHub control channel and the public ahk.aut.bme.hu warm-up stay on the + # runner's default route. Automates the manual `ip route replace` from the first live run. + for cidr in $VPN_ROUTES; do + echo "Routing $cidr via ppp0" + sudo ip route replace "$cidr" dev ppp0 + done + ip route show + # ---- E. Mount share, swap site ---- - name: Mount deployment share env: DEPLOYMENT_PATH: ${{ vars.DEPLOYMENT_PATH }} - FILE_USER: ${{ secrets.FILE_USER }} + FILE_USERNAME: ${{ vars.FILE_USERNAME }} + FILE_USERDOMAIN: ${{ vars.FILE_USERDOMAIN }} FILE_PASSWORD: ${{ secrets.FILE_PASSWORD }} run: | sudo mkdir -p "$MOUNT_POINT" sudo mount -t cifs "$DEPLOYMENT_PATH" "$MOUNT_POINT" \ - -o username="$FILE_USER",password="$FILE_PASSWORD",vers=3.0,uid=$(id -u),gid=$(id -g) + -o username="$FILE_USERNAME",domain="$FILE_USERDOMAIN",password="$FILE_PASSWORD",vers=3.0,uid=$(id -u),gid=$(id -g) - name: Stop site (drop app_offline.htm) run: | From 5739d6d3cdfde9b0a7a56f501c0eb2e9ccf6543e Mon Sep 17 00:00:00 2001 From: Bence Kovari Date: Sat, 25 Jul 2026 19:10:03 +0200 Subject: [PATCH 05/19] feat: enhance CIFS mount process to handle credentials securely --- .github/workflows/ahk-web-deploy.yaml | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ahk-web-deploy.yaml b/.github/workflows/ahk-web-deploy.yaml index 05d67feb..f42e65a0 100644 --- a/.github/workflows/ahk-web-deploy.yaml +++ b/.github/workflows/ahk-web-deploy.yaml @@ -1,4 +1,4 @@ -name: AHK Web - build, test & deploy to Mezga +name: AHK Web - Deploy to Mezga # Manual trigger only: this deploys to the on-prem IIS server behind the BME VPN. on: [workflow_dispatch] @@ -150,8 +150,24 @@ jobs: FILE_PASSWORD: ${{ secrets.FILE_PASSWORD }} run: | sudo mkdir -p "$MOUNT_POINT" - sudo mount -t cifs "$DEPLOYMENT_PATH" "$MOUNT_POINT" \ - -o username="$FILE_USERNAME",domain="$FILE_USERDOMAIN",password="$FILE_PASSWORD",vers=3.0,uid=$(id -u),gid=$(id -g) + # Pass credentials via a file, not inline -o. mount.cifs splits -o on commas, so a comma or + # other special char in the password is parsed as an option separator, silently truncating the + # password and failing auth with mount error(13) Permission denied. The file sidesteps that. + CREDS=$(mktemp) + chmod 600 "$CREDS" + { + echo "username=$FILE_USERNAME" + echo "password=$FILE_PASSWORD" + echo "domain=$FILE_USERDOMAIN" + } > "$CREDS" + if ! sudo mount -t cifs "$DEPLOYMENT_PATH" "$MOUNT_POINT" \ + -o credentials="$CREDS",vers=3.0,sec=ntlmssp,uid=$(id -u),gid=$(id -g); then + echo "::error::CIFS mount failed; recent kernel (dmesg) messages:" + sudo dmesg | tail -30 || true + rm -f "$CREDS" + exit 1 + fi + rm -f "$CREDS" - name: Stop site (drop app_offline.htm) run: | From 7bbcf4279626fa419dabda476e0d2a20770c9062 Mon Sep 17 00:00:00 2001 From: Bence Kovari Date: Thu, 30 Jul 2026 08:32:59 +0200 Subject: [PATCH 06/19] Add initial database migration, user Neptun validation tests, and web.config for server configuration - Created initial migration for database schema including tables for users, roles, courses, assignments, and related entities. - Implemented unit tests for user Neptun code validation in UsersAdminController, ensuring uniqueness and proper handling of blank values. - Added web.config to configure ASP.NET Core hosting settings and error handling. --- .claude/settings.json | 8 +- .../Ahk.Web.Data/ApplicationDbContext.cs | 6 +- .../Ahk.Web.Data/Entities/ApplicationUser.cs | 7 +- .../20260721170210_InitialCreate.Designer.cs | 836 ----------------- .../20260722162506_OidcUserClaims.Designer.cs | 847 ----------------- .../20260722162506_OidcUserClaims.cs | 69 -- ...260723112811_GitHubAccessToken.Designer.cs | 854 ------------------ .../20260723112811_GitHubAccessToken.cs | 40 - .../Migrations/20260724154747_Assignments.cs | 137 --- ... 20260730062811_InitialCreate.Designer.cs} | 8 +- ...ate.cs => 20260730062811_InitialCreate.cs} | 114 ++- .../ApplicationDbContextModelSnapshot.cs | 4 +- .../Ahk.Web.Server.Tests/UserNeptunTests.cs | 137 +++ .../Ahk.Web.Server/Admin/Dto/UserDto.cs | 4 + .../Admin/UsersAdminController.cs | 20 +- .../Ahk.Web.Server/Ahk.Web.Server.csproj | 7 + .../Auth/ExternalAuthController.cs | 29 +- ahk-backend/Ahk.Web.Server/web.config | 16 + ahk-frontend/src/app/api/api-client.ts | 1 + .../src/app/features/admin/users/users.html | 5 + .../src/app/features/admin/users/users.ts | 3 + 21 files changed, 347 insertions(+), 2805 deletions(-) delete mode 100644 ahk-backend/Ahk.Web.Data/Migrations/20260721170210_InitialCreate.Designer.cs delete mode 100644 ahk-backend/Ahk.Web.Data/Migrations/20260722162506_OidcUserClaims.Designer.cs delete mode 100644 ahk-backend/Ahk.Web.Data/Migrations/20260722162506_OidcUserClaims.cs delete mode 100644 ahk-backend/Ahk.Web.Data/Migrations/20260723112811_GitHubAccessToken.Designer.cs delete mode 100644 ahk-backend/Ahk.Web.Data/Migrations/20260723112811_GitHubAccessToken.cs delete mode 100644 ahk-backend/Ahk.Web.Data/Migrations/20260724154747_Assignments.cs rename ahk-backend/Ahk.Web.Data/Migrations/{20260724154747_Assignments.Designer.cs => 20260730062811_InitialCreate.Designer.cs} (99%) rename ahk-backend/Ahk.Web.Data/Migrations/{20260721170210_InitialCreate.cs => 20260730062811_InitialCreate.cs} (82%) create mode 100644 ahk-backend/Ahk.Web.Server.Tests/UserNeptunTests.cs create mode 100644 ahk-backend/Ahk.Web.Server/web.config diff --git a/.claude/settings.json b/.claude/settings.json index 0fb50beb..ebf3218e 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -77,7 +77,13 @@ "Bash(grep -nE \"^[0-9.]+ [0-9.]+ [0-9.]+ [0-9.]+ \\(k|K\\)$\")", "Bash(sort -u -t: -k2)", "Bash(python3 -)", - "Bash(python -c \"import yaml,sys; yaml.safe_load\\(open\\('.github/workflows/ahk-web-deploy.yaml'\\)\\); print\\('YAML OK'\\)\")" + "Bash(python -c \"import yaml,sys; yaml.safe_load\\(open\\('.github/workflows/ahk-web-deploy.yaml'\\)\\); print\\('YAML OK'\\)\")", + "Bash(cd c:/Source/ahk-github-automation/ahk-backend && dotnet publish Ahk.Web.Server/Ahk.Web.Server.csproj -p:PublishProfile=Mezga -o /tmp/ahk-webconfig-test 2>&1 | tail -3 && echo \"=== generated web.config ===\" && cat /tmp/ahk-webconfig-test/web.config 2>/dev/null || echo \"NO web.config generated\")", + "Read(//tmp/ahk-webconfig-test/**)", + "Bash(rm -rf /tmp/ahk-webconfig-test && cd c:/Source/ahk-github-automation/ahk-backend && dotnet publish Ahk.Web.Server/Ahk.Web.Server.csproj -p:PublishProfile=Mezga -o /tmp/ahk-webconfig-test 2>&1 | tail -2 && echo \"=== published web.config ===\" && cat /tmp/ahk-webconfig-test/web.config)", + "Bash(rm -rf /tmp/ahk-webconfig-test && echo cleaned)", + "PowerShell(Get-NetTCPConnection -LocalPort 7443 -State Listen -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force }; \"backend stopped\")", + "PowerShell(Get-NetTCPConnection -LocalPort 7443 -State Listen -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force }; \"checked\")" ], "additionalDirectories": [ "\\tmp" diff --git a/ahk-backend/Ahk.Web.Data/ApplicationDbContext.cs b/ahk-backend/Ahk.Web.Data/ApplicationDbContext.cs index df324f8a..068ce30d 100644 --- a/ahk-backend/Ahk.Web.Data/ApplicationDbContext.cs +++ b/ahk-backend/Ahk.Web.Data/ApplicationDbContext.cs @@ -56,8 +56,10 @@ protected override void OnModelCreating(ModelBuilder builder) e.Property(u => u.Affiliation).HasMaxLength(256); e.Property(u => u.GitHubUsername).HasMaxLength(128); - // Not unique: directory accounts may have no neptun code, and it is a lookup key, not an identity. - e.HasIndex(u => u.NeptunCode); + // Filtered unique index: a Neptun code identifies a person, so no two accounts may share one. + // NULL means "no code" (directory/local accounts may have none) and is allowed many times — + // which is why the admin controllers store null, never "", for a blank code. + e.HasIndex(u => u.NeptunCode).IsUnique().HasFilter("[NeptunCode] IS NOT NULL"); }); builder.Entity(e => diff --git a/ahk-backend/Ahk.Web.Data/Entities/ApplicationUser.cs b/ahk-backend/Ahk.Web.Data/Entities/ApplicationUser.cs index d1537886..7d2cca9d 100644 --- a/ahk-backend/Ahk.Web.Data/Entities/ApplicationUser.cs +++ b/ahk-backend/Ahk.Web.Data/Entities/ApplicationUser.cs @@ -11,9 +11,10 @@ public class ApplicationUser : IdentityUser public string? DisplayName { get; set; } /// - /// Neptun code from the IdP's neptun_code claim. Not unique here (a directory account may exist - /// without one), but it is the key of the domain model, so storing it allows linking a signed-in user to - /// their rows later. + /// Neptun code — from the IdP's neptun_code claim, or set by an admin when creating the account. + /// The key of the domain model: it links a signed-in user to their rows and is how + /// an eduID login is matched to a pre-provisioned account. Unique when present (filtered unique index); + /// null means "no code" and may repeat. /// public string? NeptunCode { get; set; } diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260721170210_InitialCreate.Designer.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260721170210_InitialCreate.Designer.cs deleted file mode 100644 index 60835431..00000000 --- a/ahk-backend/Ahk.Web.Data/Migrations/20260721170210_InitialCreate.Designer.cs +++ /dev/null @@ -1,836 +0,0 @@ -// -using System; -using Ahk.Web.Data; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -#nullable disable - -namespace Ahk.Web.Data.Migrations -{ - [DbContext(typeof(ApplicationDbContext))] - [Migration("20260721170210_InitialCreate")] - partial class InitialCreate - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.10") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("nvarchar(max)"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex") - .HasFilter("[NormalizedName] IS NOT NULL"); - - b.ToTable("AspNetRoles", (string)null); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("AccessFailedCount") - .HasColumnType("int"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("nvarchar(max)"); - - b.Property("DisplayName") - .HasColumnType("nvarchar(max)"); - - b.Property("Email") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("EmailConfirmed") - .HasColumnType("bit"); - - b.Property("LockoutEnabled") - .HasColumnType("bit"); - - b.Property("LockoutEnd") - .HasColumnType("datetimeoffset"); - - b.Property("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("PasswordHash") - .HasColumnType("nvarchar(max)"); - - b.Property("PhoneNumber") - .HasColumnType("nvarchar(max)"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("bit"); - - b.Property("SecurityStamp") - .HasColumnType("nvarchar(max)"); - - b.Property("TwoFactorEnabled") - .HasColumnType("bit"); - - b.Property("UserName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasDatabaseName("UserNameIndex") - .HasFilter("[NormalizedUserName] IS NOT NULL"); - - b.ToTable("AspNetUsers", (string)null); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CreatedAt") - .HasColumnType("datetimeoffset"); - - b.Property("GitHubOrganization") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("RepoNamePrefix") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Slug") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("Id"); - - b.HasIndex("GitHubOrganization"); - - b.HasIndex("RepoNamePrefix"); - - b.HasIndex("Slug") - .IsUnique(); - - b.ToTable("Courses"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseGitHubConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("GitHubAppId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("GitHubAppPrivateKey") - .HasColumnType("nvarchar(max)"); - - b.Property("GitHubWebhookSecret") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("WorkflowRunThreshold") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("CourseId") - .IsUnique(); - - b.ToTable("CourseGitHubConfigs"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => - { - b.Property("UserId") - .HasColumnType("int"); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("Role") - .HasColumnType("int"); - - b.HasKey("UserId", "CourseId"); - - b.HasIndex("CourseId"); - - b.ToTable("CourseMemberships"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseWebhookToken", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetimeoffset"); - - b.Property("Description") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("RevokedAt") - .HasColumnType("datetimeoffset"); - - b.Property("Secret") - .IsRequired() - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("Token") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("Id"); - - b.HasIndex("CourseId"); - - b.HasIndex("Token") - .IsUnique(); - - b.ToTable("CourseWebhookTokens"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.GradeExercisePoint", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("GradeRecordId") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Order") - .HasColumnType("int"); - - b.Property("Point") - .HasColumnType("float"); - - b.HasKey("Id"); - - b.HasIndex("GradeRecordId"); - - b.ToTable("GradeExercisePoints"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("Actor") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Confirmed") - .HasColumnType("bit"); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("Date") - .HasColumnType("datetimeoffset"); - - b.Property("Neptun") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Origin") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("PrNumber") - .HasColumnType("int"); - - b.Property("PrUrl") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("StudentId") - .HasColumnType("int"); - - b.Property("SubmissionId") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("StudentId"); - - b.HasIndex("SubmissionId"); - - b.HasIndex("CourseId", "Confirmed", "Date"); - - b.HasIndex("CourseId", "SubmissionId", "PrNumber", "Date"); - - b.ToTable("GradeRecords"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetimeoffset"); - - b.Property("GitHubUsername") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Neptun") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.HasKey("Id"); - - b.HasIndex("CourseId", "Neptun") - .IsUnique(); - - b.ToTable("Students"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetimeoffset"); - - b.Property("GitHubRepoId") - .HasColumnType("bigint"); - - b.Property("GitHubRepoName") - .IsRequired() - .HasMaxLength(400) - .HasColumnType("nvarchar(400)"); - - b.Property("LastEventAt") - .HasColumnType("datetimeoffset"); - - b.Property("StudentId") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("StudentId"); - - b.HasIndex("CourseId", "GitHubRepoName") - .IsUnique(); - - b.HasIndex("CourseId", "StudentId"); - - b.ToTable("Submissions"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.SubmissionEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(34) - .HasColumnType("nvarchar(34)"); - - b.Property("GitHubDeliveryId") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("SubmissionId") - .HasColumnType("int"); - - b.Property("Timestamp") - .HasColumnType("datetimeoffset"); - - b.HasKey("Id"); - - b.HasIndex("GitHubDeliveryId") - .IsUnique() - .HasFilter("[GitHubDeliveryId] IS NOT NULL"); - - b.HasIndex("SubmissionId"); - - b.HasIndex("CourseId", "SubmissionId", "Timestamp"); - - b.ToTable("SubmissionEvents"); - - b.HasDiscriminator("EventType").HasValue("SubmissionEvent"); - - b.UseTphMappingStrategy(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("nvarchar(max)"); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(max)"); - - b.Property("RoleId") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("nvarchar(max)"); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(max)"); - - b.Property("UserId") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("nvarchar(450)"); - - b.Property("ProviderKey") - .HasColumnType("nvarchar(450)"); - - b.Property("ProviderDisplayName") - .HasColumnType("nvarchar(max)"); - - b.Property("UserId") - .HasColumnType("int"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("int"); - - b.Property("RoleId") - .HasColumnType("int"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("int"); - - b.Property("LoginProvider") - .HasColumnType("nvarchar(450)"); - - b.Property("Name") - .HasColumnType("nvarchar(450)"); - - b.Property("Value") - .HasColumnType("nvarchar(max)"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens", (string)null); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.BranchCreatedEvent", b => - { - b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); - - b.Property("Branch") - .IsRequired() - .HasMaxLength(400) - .HasColumnType("nvarchar(400)"); - - b.HasDiscriminator().HasValue("BranchCreatedEvent"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.PullRequestEvent", b => - { - b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); - - b.Property("Action") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.PrimitiveCollection("Assignees") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("HtmlUrl") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("Neptun") - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Number") - .HasColumnType("int"); - - b.HasDiscriminator().HasValue("PullRequestEvent"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.RepositoryCreatedEvent", b => - { - b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); - - b.HasDiscriminator().HasValue("RepositoryCreatedEvent"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.WorkflowRunEvent", b => - { - b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); - - b.Property("Conclusion") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasDiscriminator().HasValue("WorkflowRunEvent"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseGitHubConfig", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithOne("GitHubConfig") - .HasForeignKey("Ahk.Web.Data.Entities.CourseGitHubConfig", "CourseId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Course"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithMany("Memberships") - .HasForeignKey("CourseId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", "User") - .WithMany("CourseMemberships") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Course"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseWebhookToken", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithMany() - .HasForeignKey("CourseId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Course"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.GradeExercisePoint", b => - { - b.HasOne("Ahk.Web.Data.Entities.GradeRecord", "GradeRecord") - .WithMany("Points") - .HasForeignKey("GradeRecordId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("GradeRecord"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithMany() - .HasForeignKey("CourseId") - .OnDelete(DeleteBehavior.NoAction) - .IsRequired(); - - b.HasOne("Ahk.Web.Data.Entities.Student", "Student") - .WithMany() - .HasForeignKey("StudentId") - .OnDelete(DeleteBehavior.NoAction); - - b.HasOne("Ahk.Web.Data.Entities.Submission", "Submission") - .WithMany("Grades") - .HasForeignKey("SubmissionId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Course"); - - b.Navigation("Student"); - - b.Navigation("Submission"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithMany() - .HasForeignKey("CourseId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Course"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithMany() - .HasForeignKey("CourseId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Ahk.Web.Data.Entities.Student", "Student") - .WithMany("Submissions") - .HasForeignKey("StudentId") - .OnDelete(DeleteBehavior.NoAction); - - b.Navigation("Course"); - - b.Navigation("Student"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.SubmissionEvent", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithMany() - .HasForeignKey("CourseId") - .OnDelete(DeleteBehavior.NoAction) - .IsRequired(); - - b.HasOne("Ahk.Web.Data.Entities.Submission", "Submission") - .WithMany("Events") - .HasForeignKey("SubmissionId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Course"); - - b.Navigation("Submission"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => - { - b.Navigation("CourseMemberships"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => - { - b.Navigation("GitHubConfig"); - - b.Navigation("Memberships"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => - { - b.Navigation("Points"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => - { - b.Navigation("Submissions"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => - { - b.Navigation("Events"); - - b.Navigation("Grades"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260722162506_OidcUserClaims.Designer.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260722162506_OidcUserClaims.Designer.cs deleted file mode 100644 index 2035a568..00000000 --- a/ahk-backend/Ahk.Web.Data/Migrations/20260722162506_OidcUserClaims.Designer.cs +++ /dev/null @@ -1,847 +0,0 @@ -// -using System; -using Ahk.Web.Data; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -#nullable disable - -namespace Ahk.Web.Data.Migrations -{ - [DbContext(typeof(ApplicationDbContext))] - [Migration("20260722162506_OidcUserClaims")] - partial class OidcUserClaims - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.10") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("nvarchar(max)"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex") - .HasFilter("[NormalizedName] IS NOT NULL"); - - b.ToTable("AspNetRoles", (string)null); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("AccessFailedCount") - .HasColumnType("int"); - - b.Property("Affiliation") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("nvarchar(max)"); - - b.Property("DisplayName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Email") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("EmailConfirmed") - .HasColumnType("bit"); - - b.Property("LockoutEnabled") - .HasColumnType("bit"); - - b.Property("LockoutEnd") - .HasColumnType("datetimeoffset"); - - b.Property("NeptunCode") - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("PasswordHash") - .HasColumnType("nvarchar(max)"); - - b.Property("PhoneNumber") - .HasColumnType("nvarchar(max)"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("bit"); - - b.Property("SecurityStamp") - .HasColumnType("nvarchar(max)"); - - b.Property("TwoFactorEnabled") - .HasColumnType("bit"); - - b.Property("UserName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.HasKey("Id"); - - b.HasIndex("NeptunCode"); - - b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasDatabaseName("UserNameIndex") - .HasFilter("[NormalizedUserName] IS NOT NULL"); - - b.ToTable("AspNetUsers", (string)null); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CreatedAt") - .HasColumnType("datetimeoffset"); - - b.Property("GitHubOrganization") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("RepoNamePrefix") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Slug") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("Id"); - - b.HasIndex("GitHubOrganization"); - - b.HasIndex("RepoNamePrefix"); - - b.HasIndex("Slug") - .IsUnique(); - - b.ToTable("Courses"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseGitHubConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("GitHubAppId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("GitHubAppPrivateKey") - .HasColumnType("nvarchar(max)"); - - b.Property("GitHubWebhookSecret") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("WorkflowRunThreshold") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("CourseId") - .IsUnique(); - - b.ToTable("CourseGitHubConfigs"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => - { - b.Property("UserId") - .HasColumnType("int"); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("Role") - .HasColumnType("int"); - - b.HasKey("UserId", "CourseId"); - - b.HasIndex("CourseId"); - - b.ToTable("CourseMemberships"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseWebhookToken", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetimeoffset"); - - b.Property("Description") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("RevokedAt") - .HasColumnType("datetimeoffset"); - - b.Property("Secret") - .IsRequired() - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("Token") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("Id"); - - b.HasIndex("CourseId"); - - b.HasIndex("Token") - .IsUnique(); - - b.ToTable("CourseWebhookTokens"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.GradeExercisePoint", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("GradeRecordId") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Order") - .HasColumnType("int"); - - b.Property("Point") - .HasColumnType("float"); - - b.HasKey("Id"); - - b.HasIndex("GradeRecordId"); - - b.ToTable("GradeExercisePoints"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("Actor") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Confirmed") - .HasColumnType("bit"); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("Date") - .HasColumnType("datetimeoffset"); - - b.Property("Neptun") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Origin") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("PrNumber") - .HasColumnType("int"); - - b.Property("PrUrl") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("StudentId") - .HasColumnType("int"); - - b.Property("SubmissionId") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("StudentId"); - - b.HasIndex("SubmissionId"); - - b.HasIndex("CourseId", "Confirmed", "Date"); - - b.HasIndex("CourseId", "SubmissionId", "PrNumber", "Date"); - - b.ToTable("GradeRecords"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetimeoffset"); - - b.Property("GitHubUsername") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Neptun") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.HasKey("Id"); - - b.HasIndex("CourseId", "Neptun") - .IsUnique(); - - b.ToTable("Students"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetimeoffset"); - - b.Property("GitHubRepoId") - .HasColumnType("bigint"); - - b.Property("GitHubRepoName") - .IsRequired() - .HasMaxLength(400) - .HasColumnType("nvarchar(400)"); - - b.Property("LastEventAt") - .HasColumnType("datetimeoffset"); - - b.Property("StudentId") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("StudentId"); - - b.HasIndex("CourseId", "GitHubRepoName") - .IsUnique(); - - b.HasIndex("CourseId", "StudentId"); - - b.ToTable("Submissions"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.SubmissionEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(34) - .HasColumnType("nvarchar(34)"); - - b.Property("GitHubDeliveryId") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("SubmissionId") - .HasColumnType("int"); - - b.Property("Timestamp") - .HasColumnType("datetimeoffset"); - - b.HasKey("Id"); - - b.HasIndex("GitHubDeliveryId") - .IsUnique() - .HasFilter("[GitHubDeliveryId] IS NOT NULL"); - - b.HasIndex("SubmissionId"); - - b.HasIndex("CourseId", "SubmissionId", "Timestamp"); - - b.ToTable("SubmissionEvents"); - - b.HasDiscriminator("EventType").HasValue("SubmissionEvent"); - - b.UseTphMappingStrategy(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("nvarchar(max)"); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(max)"); - - b.Property("RoleId") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("nvarchar(max)"); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(max)"); - - b.Property("UserId") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("nvarchar(450)"); - - b.Property("ProviderKey") - .HasColumnType("nvarchar(450)"); - - b.Property("ProviderDisplayName") - .HasColumnType("nvarchar(max)"); - - b.Property("UserId") - .HasColumnType("int"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("int"); - - b.Property("RoleId") - .HasColumnType("int"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("int"); - - b.Property("LoginProvider") - .HasColumnType("nvarchar(450)"); - - b.Property("Name") - .HasColumnType("nvarchar(450)"); - - b.Property("Value") - .HasColumnType("nvarchar(max)"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens", (string)null); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.BranchCreatedEvent", b => - { - b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); - - b.Property("Branch") - .IsRequired() - .HasMaxLength(400) - .HasColumnType("nvarchar(400)"); - - b.HasDiscriminator().HasValue("BranchCreatedEvent"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.PullRequestEvent", b => - { - b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); - - b.Property("Action") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.PrimitiveCollection("Assignees") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("HtmlUrl") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("Neptun") - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Number") - .HasColumnType("int"); - - b.HasDiscriminator().HasValue("PullRequestEvent"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.RepositoryCreatedEvent", b => - { - b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); - - b.HasDiscriminator().HasValue("RepositoryCreatedEvent"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.WorkflowRunEvent", b => - { - b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); - - b.Property("Conclusion") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasDiscriminator().HasValue("WorkflowRunEvent"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseGitHubConfig", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithOne("GitHubConfig") - .HasForeignKey("Ahk.Web.Data.Entities.CourseGitHubConfig", "CourseId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Course"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithMany("Memberships") - .HasForeignKey("CourseId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", "User") - .WithMany("CourseMemberships") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Course"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseWebhookToken", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithMany() - .HasForeignKey("CourseId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Course"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.GradeExercisePoint", b => - { - b.HasOne("Ahk.Web.Data.Entities.GradeRecord", "GradeRecord") - .WithMany("Points") - .HasForeignKey("GradeRecordId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("GradeRecord"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithMany() - .HasForeignKey("CourseId") - .OnDelete(DeleteBehavior.NoAction) - .IsRequired(); - - b.HasOne("Ahk.Web.Data.Entities.Student", "Student") - .WithMany() - .HasForeignKey("StudentId") - .OnDelete(DeleteBehavior.NoAction); - - b.HasOne("Ahk.Web.Data.Entities.Submission", "Submission") - .WithMany("Grades") - .HasForeignKey("SubmissionId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Course"); - - b.Navigation("Student"); - - b.Navigation("Submission"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithMany() - .HasForeignKey("CourseId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Course"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithMany() - .HasForeignKey("CourseId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Ahk.Web.Data.Entities.Student", "Student") - .WithMany("Submissions") - .HasForeignKey("StudentId") - .OnDelete(DeleteBehavior.NoAction); - - b.Navigation("Course"); - - b.Navigation("Student"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.SubmissionEvent", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithMany() - .HasForeignKey("CourseId") - .OnDelete(DeleteBehavior.NoAction) - .IsRequired(); - - b.HasOne("Ahk.Web.Data.Entities.Submission", "Submission") - .WithMany("Events") - .HasForeignKey("SubmissionId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Course"); - - b.Navigation("Submission"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => - { - b.Navigation("CourseMemberships"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => - { - b.Navigation("GitHubConfig"); - - b.Navigation("Memberships"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => - { - b.Navigation("Points"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => - { - b.Navigation("Submissions"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => - { - b.Navigation("Events"); - - b.Navigation("Grades"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260722162506_OidcUserClaims.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260722162506_OidcUserClaims.cs deleted file mode 100644 index 53b675e6..00000000 --- a/ahk-backend/Ahk.Web.Data/Migrations/20260722162506_OidcUserClaims.cs +++ /dev/null @@ -1,69 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Ahk.Web.Data.Migrations -{ - /// - public partial class OidcUserClaims : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterColumn( - name: "DisplayName", - table: "AspNetUsers", - type: "nvarchar(256)", - maxLength: 256, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(max)", - oldNullable: true); - - migrationBuilder.AddColumn( - name: "Affiliation", - table: "AspNetUsers", - type: "nvarchar(256)", - maxLength: 256, - nullable: true); - - migrationBuilder.AddColumn( - name: "NeptunCode", - table: "AspNetUsers", - type: "nvarchar(32)", - maxLength: 32, - nullable: true); - - migrationBuilder.CreateIndex( - name: "IX_AspNetUsers_NeptunCode", - table: "AspNetUsers", - column: "NeptunCode"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropIndex( - name: "IX_AspNetUsers_NeptunCode", - table: "AspNetUsers"); - - migrationBuilder.DropColumn( - name: "Affiliation", - table: "AspNetUsers"); - - migrationBuilder.DropColumn( - name: "NeptunCode", - table: "AspNetUsers"); - - migrationBuilder.AlterColumn( - name: "DisplayName", - table: "AspNetUsers", - type: "nvarchar(max)", - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(256)", - oldMaxLength: 256, - oldNullable: true); - } - } -} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260723112811_GitHubAccessToken.Designer.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260723112811_GitHubAccessToken.Designer.cs deleted file mode 100644 index d08dbebb..00000000 --- a/ahk-backend/Ahk.Web.Data/Migrations/20260723112811_GitHubAccessToken.Designer.cs +++ /dev/null @@ -1,854 +0,0 @@ -// -using System; -using Ahk.Web.Data; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -#nullable disable - -namespace Ahk.Web.Data.Migrations -{ - [DbContext(typeof(ApplicationDbContext))] - [Migration("20260723112811_GitHubAccessToken")] - partial class GitHubAccessToken - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "10.0.10") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationRole", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("nvarchar(max)"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex") - .HasFilter("[NormalizedName] IS NOT NULL"); - - b.ToTable("AspNetRoles", (string)null); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("AccessFailedCount") - .HasColumnType("int"); - - b.Property("Affiliation") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("nvarchar(max)"); - - b.Property("DisplayName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Email") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("EmailConfirmed") - .HasColumnType("bit"); - - b.Property("LockoutEnabled") - .HasColumnType("bit"); - - b.Property("LockoutEnd") - .HasColumnType("datetimeoffset"); - - b.Property("NeptunCode") - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("PasswordHash") - .HasColumnType("nvarchar(max)"); - - b.Property("PhoneNumber") - .HasColumnType("nvarchar(max)"); - - b.Property("PhoneNumberConfirmed") - .HasColumnType("bit"); - - b.Property("SecurityStamp") - .HasColumnType("nvarchar(max)"); - - b.Property("TwoFactorEnabled") - .HasColumnType("bit"); - - b.Property("UserName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.HasKey("Id"); - - b.HasIndex("NeptunCode"); - - b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasDatabaseName("UserNameIndex") - .HasFilter("[NormalizedUserName] IS NOT NULL"); - - b.ToTable("AspNetUsers", (string)null); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CreatedAt") - .HasColumnType("datetimeoffset"); - - b.Property("GitHubOrganization") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("RepoNamePrefix") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Slug") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasKey("Id"); - - b.HasIndex("GitHubOrganization"); - - b.HasIndex("RepoNamePrefix"); - - b.HasIndex("Slug") - .IsUnique(); - - b.ToTable("Courses"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseGitHubConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("Enabled") - .HasColumnType("bit"); - - b.Property("GitHubAccessToken") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("GitHubAppId") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.Property("GitHubAppPrivateKey") - .HasColumnType("nvarchar(max)"); - - b.Property("GitHubWebhookSecret") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("UpdatedAt") - .HasColumnType("datetimeoffset"); - - b.Property("WorkflowRunThreshold") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("CourseId") - .IsUnique(); - - b.ToTable("CourseGitHubConfigs"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => - { - b.Property("UserId") - .HasColumnType("int"); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("Role") - .HasColumnType("int"); - - b.HasKey("UserId", "CourseId"); - - b.HasIndex("CourseId"); - - b.ToTable("CourseMemberships"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseWebhookToken", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetimeoffset"); - - b.Property("Description") - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("RevokedAt") - .HasColumnType("datetimeoffset"); - - b.Property("Secret") - .IsRequired() - .HasMaxLength(512) - .HasColumnType("nvarchar(512)"); - - b.Property("Token") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.HasKey("Id"); - - b.HasIndex("CourseId"); - - b.HasIndex("Token") - .IsUnique(); - - b.ToTable("CourseWebhookTokens"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.GradeExercisePoint", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("GradeRecordId") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Order") - .HasColumnType("int"); - - b.Property("Point") - .HasColumnType("float"); - - b.HasKey("Id"); - - b.HasIndex("GradeRecordId"); - - b.ToTable("GradeExercisePoints"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("Actor") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Confirmed") - .HasColumnType("bit"); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("Date") - .HasColumnType("datetimeoffset"); - - b.Property("Neptun") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Origin") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("PrNumber") - .HasColumnType("int"); - - b.Property("PrUrl") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("StudentId") - .HasColumnType("int"); - - b.Property("SubmissionId") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("StudentId"); - - b.HasIndex("SubmissionId"); - - b.HasIndex("CourseId", "Confirmed", "Date"); - - b.HasIndex("CourseId", "SubmissionId", "PrNumber", "Date"); - - b.ToTable("GradeRecords"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetimeoffset"); - - b.Property("GitHubUsername") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("Neptun") - .IsRequired() - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.HasKey("Id"); - - b.HasIndex("CourseId", "Neptun") - .IsUnique(); - - b.ToTable("Students"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("CreatedAt") - .HasColumnType("datetimeoffset"); - - b.Property("GitHubRepoId") - .HasColumnType("bigint"); - - b.Property("GitHubRepoName") - .IsRequired() - .HasMaxLength(400) - .HasColumnType("nvarchar(400)"); - - b.Property("LastEventAt") - .HasColumnType("datetimeoffset"); - - b.Property("StudentId") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("StudentId"); - - b.HasIndex("CourseId", "GitHubRepoName") - .IsUnique(); - - b.HasIndex("CourseId", "StudentId"); - - b.ToTable("Submissions"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.SubmissionEvent", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("CourseId") - .HasColumnType("int"); - - b.Property("EventType") - .IsRequired() - .HasMaxLength(34) - .HasColumnType("nvarchar(34)"); - - b.Property("GitHubDeliveryId") - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - - b.Property("SubmissionId") - .HasColumnType("int"); - - b.Property("Timestamp") - .HasColumnType("datetimeoffset"); - - b.HasKey("Id"); - - b.HasIndex("GitHubDeliveryId") - .IsUnique() - .HasFilter("[GitHubDeliveryId] IS NOT NULL"); - - b.HasIndex("SubmissionId"); - - b.HasIndex("CourseId", "SubmissionId", "Timestamp"); - - b.ToTable("SubmissionEvents"); - - b.HasDiscriminator("EventType").HasValue("SubmissionEvent"); - - b.UseTphMappingStrategy(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("nvarchar(max)"); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(max)"); - - b.Property("RoleId") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("nvarchar(max)"); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(max)"); - - b.Property("UserId") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("nvarchar(450)"); - - b.Property("ProviderKey") - .HasColumnType("nvarchar(450)"); - - b.Property("ProviderDisplayName") - .HasColumnType("nvarchar(max)"); - - b.Property("UserId") - .HasColumnType("int"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("int"); - - b.Property("RoleId") - .HasColumnType("int"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("int"); - - b.Property("LoginProvider") - .HasColumnType("nvarchar(450)"); - - b.Property("Name") - .HasColumnType("nvarchar(450)"); - - b.Property("Value") - .HasColumnType("nvarchar(max)"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens", (string)null); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.BranchCreatedEvent", b => - { - b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); - - b.Property("Branch") - .IsRequired() - .HasMaxLength(400) - .HasColumnType("nvarchar(400)"); - - b.HasDiscriminator().HasValue("BranchCreatedEvent"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.PullRequestEvent", b => - { - b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); - - b.Property("Action") - .IsRequired() - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.PrimitiveCollection("Assignees") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("HtmlUrl") - .HasMaxLength(1024) - .HasColumnType("nvarchar(1024)"); - - b.Property("Neptun") - .HasMaxLength(32) - .HasColumnType("nvarchar(32)"); - - b.Property("Number") - .HasColumnType("int"); - - b.HasDiscriminator().HasValue("PullRequestEvent"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.RepositoryCreatedEvent", b => - { - b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); - - b.HasDiscriminator().HasValue("RepositoryCreatedEvent"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.WorkflowRunEvent", b => - { - b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); - - b.Property("Conclusion") - .HasMaxLength(64) - .HasColumnType("nvarchar(64)"); - - b.HasDiscriminator().HasValue("WorkflowRunEvent"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseGitHubConfig", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithOne("GitHubConfig") - .HasForeignKey("Ahk.Web.Data.Entities.CourseGitHubConfig", "CourseId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Course"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithMany("Memberships") - .HasForeignKey("CourseId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", "User") - .WithMany("CourseMemberships") - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Course"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.CourseWebhookToken", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithMany() - .HasForeignKey("CourseId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Course"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.GradeExercisePoint", b => - { - b.HasOne("Ahk.Web.Data.Entities.GradeRecord", "GradeRecord") - .WithMany("Points") - .HasForeignKey("GradeRecordId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("GradeRecord"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithMany() - .HasForeignKey("CourseId") - .OnDelete(DeleteBehavior.NoAction) - .IsRequired(); - - b.HasOne("Ahk.Web.Data.Entities.Student", "Student") - .WithMany() - .HasForeignKey("StudentId") - .OnDelete(DeleteBehavior.NoAction); - - b.HasOne("Ahk.Web.Data.Entities.Submission", "Submission") - .WithMany("Grades") - .HasForeignKey("SubmissionId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Course"); - - b.Navigation("Student"); - - b.Navigation("Submission"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithMany() - .HasForeignKey("CourseId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Course"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithMany() - .HasForeignKey("CourseId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Ahk.Web.Data.Entities.Student", "Student") - .WithMany("Submissions") - .HasForeignKey("StudentId") - .OnDelete(DeleteBehavior.NoAction); - - b.Navigation("Course"); - - b.Navigation("Student"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.SubmissionEvent", b => - { - b.HasOne("Ahk.Web.Data.Entities.Course", "Course") - .WithMany() - .HasForeignKey("CourseId") - .OnDelete(DeleteBehavior.NoAction) - .IsRequired(); - - b.HasOne("Ahk.Web.Data.Entities.Submission", "Submission") - .WithMany("Events") - .HasForeignKey("SubmissionId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Course"); - - b.Navigation("Submission"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => - { - b.Navigation("CourseMemberships"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => - { - b.Navigation("GitHubConfig"); - - b.Navigation("Memberships"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => - { - b.Navigation("Points"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => - { - b.Navigation("Submissions"); - }); - - modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => - { - b.Navigation("Events"); - - b.Navigation("Grades"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260723112811_GitHubAccessToken.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260723112811_GitHubAccessToken.cs deleted file mode 100644 index 59a73a6f..00000000 --- a/ahk-backend/Ahk.Web.Data/Migrations/20260723112811_GitHubAccessToken.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Ahk.Web.Data.Migrations -{ - /// - public partial class GitHubAccessToken : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "GitHubAccessToken", - table: "CourseGitHubConfigs", - type: "nvarchar(512)", - maxLength: 512, - nullable: true); - - migrationBuilder.AddColumn( - name: "UpdatedAt", - table: "CourseGitHubConfigs", - type: "datetimeoffset", - nullable: true); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "GitHubAccessToken", - table: "CourseGitHubConfigs"); - - migrationBuilder.DropColumn( - name: "UpdatedAt", - table: "CourseGitHubConfigs"); - } - } -} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260724154747_Assignments.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260724154747_Assignments.cs deleted file mode 100644 index b3970bdb..00000000 --- a/ahk-backend/Ahk.Web.Data/Migrations/20260724154747_Assignments.cs +++ /dev/null @@ -1,137 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Ahk.Web.Data.Migrations -{ - /// - public partial class Assignments : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "GitHubUserId", - table: "AspNetUsers", - type: "bigint", - nullable: true); - - migrationBuilder.AddColumn( - name: "GitHubUsername", - table: "AspNetUsers", - type: "nvarchar(128)", - maxLength: 128, - nullable: true); - - migrationBuilder.CreateTable( - name: "Assignments", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - CourseId = table.Column(type: "int", nullable: false), - Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), - Description = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true), - TemplateRepoName = table.Column(type: "nvarchar(400)", maxLength: 400, nullable: false), - InviteToken = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - ArchivedAt = table.Column(type: "datetimeoffset", nullable: true), - CreatedAt = table.Column(type: "datetimeoffset", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Assignments", x => x.Id); - table.ForeignKey( - name: "FK_Assignments_Courses_CourseId", - column: x => x.CourseId, - principalTable: "Courses", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AssignmentAcceptances", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("SqlServer:Identity", "1, 1"), - CourseId = table.Column(type: "int", nullable: false), - AssignmentId = table.Column(type: "int", nullable: false), - UserId = table.Column(type: "int", nullable: false), - GitHubRepoName = table.Column(type: "nvarchar(400)", maxLength: 400, nullable: false), - RepoUrl = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: false), - GitHubUsername = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), - AcceptedAt = table.Column(type: "datetimeoffset", nullable: false), - InvitationPending = table.Column(type: "bit", nullable: false), - InvitationId = table.Column(type: "bigint", nullable: true), - InvitationSentAt = table.Column(type: "datetimeoffset", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AssignmentAcceptances", x => x.Id); - table.ForeignKey( - name: "FK_AssignmentAcceptances_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_AssignmentAcceptances_Assignments_AssignmentId", - column: x => x.AssignmentId, - principalTable: "Assignments", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_AssignmentAcceptances_Courses_CourseId", - column: x => x.CourseId, - principalTable: "Courses", - principalColumn: "Id"); - }); - - migrationBuilder.CreateIndex( - name: "IX_AssignmentAcceptances_AssignmentId_UserId", - table: "AssignmentAcceptances", - columns: new[] { "AssignmentId", "UserId" }, - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_AssignmentAcceptances_CourseId_GitHubRepoName", - table: "AssignmentAcceptances", - columns: new[] { "CourseId", "GitHubRepoName" }); - - migrationBuilder.CreateIndex( - name: "IX_AssignmentAcceptances_UserId", - table: "AssignmentAcceptances", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_Assignments_CourseId_ArchivedAt", - table: "Assignments", - columns: new[] { "CourseId", "ArchivedAt" }); - - migrationBuilder.CreateIndex( - name: "IX_Assignments_InviteToken", - table: "Assignments", - column: "InviteToken", - unique: true); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "AssignmentAcceptances"); - - migrationBuilder.DropTable( - name: "Assignments"); - - migrationBuilder.DropColumn( - name: "GitHubUserId", - table: "AspNetUsers"); - - migrationBuilder.DropColumn( - name: "GitHubUsername", - table: "AspNetUsers"); - } - } -} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260724154747_Assignments.Designer.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260730062811_InitialCreate.Designer.cs similarity index 99% rename from ahk-backend/Ahk.Web.Data/Migrations/20260724154747_Assignments.Designer.cs rename to ahk-backend/Ahk.Web.Data/Migrations/20260730062811_InitialCreate.Designer.cs index 8420bf17..420c03f6 100644 --- a/ahk-backend/Ahk.Web.Data/Migrations/20260724154747_Assignments.Designer.cs +++ b/ahk-backend/Ahk.Web.Data/Migrations/20260730062811_InitialCreate.Designer.cs @@ -12,8 +12,8 @@ namespace Ahk.Web.Data.Migrations { [DbContext(typeof(ApplicationDbContext))] - [Migration("20260724154747_Assignments")] - partial class Assignments + [Migration("20260730062811_InitialCreate")] + partial class InitialCreate { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -131,7 +131,9 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.HasIndex("NeptunCode"); + b.HasIndex("NeptunCode") + .IsUnique() + .HasFilter("[NeptunCode] IS NOT NULL"); b.HasIndex("NormalizedEmail") .HasDatabaseName("EmailIndex"); diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260721170210_InitialCreate.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260730062811_InitialCreate.cs similarity index 82% rename from ahk-backend/Ahk.Web.Data/Migrations/20260721170210_InitialCreate.cs rename to ahk-backend/Ahk.Web.Data/Migrations/20260730062811_InitialCreate.cs index 8bfee552..48418725 100644 --- a/ahk-backend/Ahk.Web.Data/Migrations/20260721170210_InitialCreate.cs +++ b/ahk-backend/Ahk.Web.Data/Migrations/20260730062811_InitialCreate.cs @@ -32,7 +32,11 @@ protected override void Up(MigrationBuilder migrationBuilder) { Id = table.Column(type: "int", nullable: false) .Annotation("SqlServer:Identity", "1, 1"), - DisplayName = table.Column(type: "nvarchar(max)", nullable: true), + DisplayName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + NeptunCode = table.Column(type: "nvarchar(32)", maxLength: 32, nullable: true), + Affiliation = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + GitHubUsername = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: true), + GitHubUserId = table.Column(type: "bigint", nullable: true), UserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), NormalizedUserName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), Email = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), @@ -176,6 +180,31 @@ protected override void Up(MigrationBuilder migrationBuilder) onDelete: ReferentialAction.Cascade); }); + migrationBuilder.CreateTable( + name: "Assignments", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + CourseId = table.Column(type: "int", nullable: false), + Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + Description = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: true), + TemplateRepoName = table.Column(type: "nvarchar(400)", maxLength: 400, nullable: false), + InviteToken = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + ArchivedAt = table.Column(type: "datetimeoffset", nullable: true), + CreatedAt = table.Column(type: "datetimeoffset", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Assignments", x => x.Id); + table.ForeignKey( + name: "FK_Assignments_Courses_CourseId", + column: x => x.CourseId, + principalTable: "Courses", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + migrationBuilder.CreateTable( name: "CourseGitHubConfigs", columns: table => new @@ -185,9 +214,11 @@ protected override void Up(MigrationBuilder migrationBuilder) CourseId = table.Column(type: "int", nullable: false), GitHubAppId = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: true), GitHubAppPrivateKey = table.Column(type: "nvarchar(max)", nullable: true), + GitHubAccessToken = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), GitHubWebhookSecret = table.Column(type: "nvarchar(512)", maxLength: 512, nullable: true), WorkflowRunThreshold = table.Column(type: "int", nullable: false), - Enabled = table.Column(type: "bit", nullable: false) + Enabled = table.Column(type: "bit", nullable: false), + UpdatedAt = table.Column(type: "datetimeoffset", nullable: true) }, constraints: table => { @@ -272,6 +303,45 @@ protected override void Up(MigrationBuilder migrationBuilder) onDelete: ReferentialAction.Cascade); }); + migrationBuilder.CreateTable( + name: "AssignmentAcceptances", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + CourseId = table.Column(type: "int", nullable: false), + AssignmentId = table.Column(type: "int", nullable: false), + UserId = table.Column(type: "int", nullable: false), + GitHubRepoName = table.Column(type: "nvarchar(400)", maxLength: 400, nullable: false), + RepoUrl = table.Column(type: "nvarchar(1024)", maxLength: 1024, nullable: false), + GitHubUsername = table.Column(type: "nvarchar(128)", maxLength: 128, nullable: false), + AcceptedAt = table.Column(type: "datetimeoffset", nullable: false), + InvitationPending = table.Column(type: "bit", nullable: false), + InvitationId = table.Column(type: "bigint", nullable: true), + InvitationSentAt = table.Column(type: "datetimeoffset", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AssignmentAcceptances", x => x.Id); + table.ForeignKey( + name: "FK_AssignmentAcceptances_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AssignmentAcceptances_Assignments_AssignmentId", + column: x => x.AssignmentId, + principalTable: "Assignments", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AssignmentAcceptances_Courses_CourseId", + column: x => x.CourseId, + principalTable: "Courses", + principalColumn: "Id"); + }); + migrationBuilder.CreateTable( name: "Submissions", columns: table => new @@ -428,6 +498,13 @@ protected override void Up(MigrationBuilder migrationBuilder) table: "AspNetUsers", column: "NormalizedEmail"); + migrationBuilder.CreateIndex( + name: "IX_AspNetUsers_NeptunCode", + table: "AspNetUsers", + column: "NeptunCode", + unique: true, + filter: "[NeptunCode] IS NOT NULL"); + migrationBuilder.CreateIndex( name: "UserNameIndex", table: "AspNetUsers", @@ -435,6 +512,33 @@ protected override void Up(MigrationBuilder migrationBuilder) unique: true, filter: "[NormalizedUserName] IS NOT NULL"); + migrationBuilder.CreateIndex( + name: "IX_AssignmentAcceptances_AssignmentId_UserId", + table: "AssignmentAcceptances", + columns: new[] { "AssignmentId", "UserId" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_AssignmentAcceptances_CourseId_GitHubRepoName", + table: "AssignmentAcceptances", + columns: new[] { "CourseId", "GitHubRepoName" }); + + migrationBuilder.CreateIndex( + name: "IX_AssignmentAcceptances_UserId", + table: "AssignmentAcceptances", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_Assignments_CourseId_ArchivedAt", + table: "Assignments", + columns: new[] { "CourseId", "ArchivedAt" }); + + migrationBuilder.CreateIndex( + name: "IX_Assignments_InviteToken", + table: "Assignments", + column: "InviteToken", + unique: true); + migrationBuilder.CreateIndex( name: "IX_CourseGitHubConfigs_CourseId", table: "CourseGitHubConfigs", @@ -556,6 +660,9 @@ protected override void Down(MigrationBuilder migrationBuilder) migrationBuilder.DropTable( name: "AspNetUserTokens"); + migrationBuilder.DropTable( + name: "AssignmentAcceptances"); + migrationBuilder.DropTable( name: "CourseGitHubConfigs"); @@ -574,6 +681,9 @@ protected override void Down(MigrationBuilder migrationBuilder) migrationBuilder.DropTable( name: "AspNetRoles"); + migrationBuilder.DropTable( + name: "Assignments"); + migrationBuilder.DropTable( name: "AspNetUsers"); diff --git a/ahk-backend/Ahk.Web.Data/Migrations/ApplicationDbContextModelSnapshot.cs b/ahk-backend/Ahk.Web.Data/Migrations/ApplicationDbContextModelSnapshot.cs index 49c0f5de..e17d116b 100644 --- a/ahk-backend/Ahk.Web.Data/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/ahk-backend/Ahk.Web.Data/Migrations/ApplicationDbContextModelSnapshot.cs @@ -128,7 +128,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.HasIndex("NeptunCode"); + b.HasIndex("NeptunCode") + .IsUnique() + .HasFilter("[NeptunCode] IS NOT NULL"); b.HasIndex("NormalizedEmail") .HasDatabaseName("EmailIndex"); diff --git a/ahk-backend/Ahk.Web.Server.Tests/UserNeptunTests.cs b/ahk-backend/Ahk.Web.Server.Tests/UserNeptunTests.cs new file mode 100644 index 00000000..80736fd7 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server.Tests/UserNeptunTests.cs @@ -0,0 +1,137 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Ahk.Web.Server.Admin; +using Ahk.Web.Server.Admin.Dto; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; +using Xunit; + +namespace Ahk.Web.Server.Tests; + +/// +/// The admin rule that a Neptun code is either empty or unique across users, exercised through +/// over a real on the in-memory store. +/// (EF InMemory does not enforce the filtered unique index, so this proves the controller's own guard — +/// the database index is the backstop in production.) +/// +public sealed class UserNeptunTests : IDisposable +{ + private readonly ApplicationDbContext db; + private readonly UserManager userManager; + private readonly UsersAdminController controller; + + public UserNeptunTests() + { + var options = new DbContextOptionsBuilder() + .UseInMemoryDatabase($"UserNeptunTests-{Guid.NewGuid()}") + .Options; + this.db = new ApplicationDbContext(options, new NoCourse()); + + var store = new UserStore(this.db); + this.userManager = new UserManager( + store, + Options.Create(new IdentityOptions()), + new PasswordHasher(), + Array.Empty>(), + Array.Empty>(), + new UpperInvariantLookupNormalizer(), + new IdentityErrorDescriber(), + services: null!, + NullLogger>.Instance); + + this.controller = new UsersAdminController(this.db, this.userManager); + } + + [Fact] + public async Task Create_StoresNeptunUppercased() + { + var result = await this.controller.Create(NewUser("alice", neptun: "abc123"), default); + + var dto = Assert.IsType(Assert.IsType(result.Result).Value); + Assert.Equal("ABC123", dto.NeptunCode); + Assert.Equal("ABC123", (await this.userManager.FindByNameAsync("alice"))!.NeptunCode); + } + + [Fact] + public async Task Create_DuplicateNeptun_IsRejected() + { + await this.controller.Create(NewUser("alice", neptun: "ABC123"), default); + + // Same code, different casing/whitespace — normalization must make them collide. + var result = await this.controller.Create(NewUser("bob", neptun: " abc123 "), default); + + Assert.IsType(result.Result); + Assert.Null(await this.userManager.FindByNameAsync("bob")); // not created + } + + [Fact] + public async Task Create_BlankNeptun_StoredAsNull_AndMayRepeat() + { + await this.controller.Create(NewUser("alice", neptun: ""), default); + var result = await this.controller.Create(NewUser("bob", neptun: " "), default); + + Assert.IsType(result.Result); + Assert.Null((await this.userManager.FindByNameAsync("alice"))!.NeptunCode); + Assert.Null((await this.userManager.FindByNameAsync("bob"))!.NeptunCode); + } + + [Fact] + public async Task Update_ToNeptunHeldByAnother_IsRejected() + { + await this.controller.Create(NewUser("alice", neptun: "ALICE1"), default); + await this.controller.Create(NewUser("bob", neptun: "BOB1"), default); + var bob = (await this.userManager.FindByNameAsync("bob"))!; + + var result = await this.controller.Update(bob.Id, new UpdateUserRequest { NeptunCode = "alice1" }, default); + + Assert.IsType(result.Result); + Assert.Equal("BOB1", (await this.userManager.FindByNameAsync("bob"))!.NeptunCode); // unchanged + } + + [Fact] + public async Task Update_KeepingOwnNeptun_Succeeds() + { + await this.controller.Create(NewUser("alice", neptun: "ALICE1"), default); + var alice = (await this.userManager.FindByNameAsync("alice"))!; + + var result = await this.controller.Update(alice.Id, new UpdateUserRequest { NeptunCode = "alice1" }, default); + + Assert.IsType(Assert.IsType(result.Result).Value); + Assert.Equal("ALICE1", (await this.userManager.FindByNameAsync("alice"))!.NeptunCode); + } + + [Fact] + public async Task Update_ClearingNeptun_StoresNull() + { + await this.controller.Create(NewUser("alice", neptun: "ALICE1"), default); + var alice = (await this.userManager.FindByNameAsync("alice"))!; + + await this.controller.Update(alice.Id, new UpdateUserRequest { NeptunCode = "" }, default); + + Assert.Null((await this.userManager.FindByNameAsync("alice"))!.NeptunCode); + } + + private static CreateUserRequest NewUser(string userName, string? neptun) => new() + { + UserName = userName, + Password = "Passw0rd!", + NeptunCode = neptun, + }; + + public void Dispose() + { + this.userManager.Dispose(); + this.db.Dispose(); + } + + /// Course provider that resolves no course; is not course-scoped, so + /// the value is irrelevant here. + private sealed class NoCourse : ICurrentCourseProvider + { + public int? CurrentCourseId => null; + } +} diff --git a/ahk-backend/Ahk.Web.Server/Admin/Dto/UserDto.cs b/ahk-backend/Ahk.Web.Server/Admin/Dto/UserDto.cs index 82acc80a..44750f76 100644 --- a/ahk-backend/Ahk.Web.Server/Admin/Dto/UserDto.cs +++ b/ahk-backend/Ahk.Web.Server/Admin/Dto/UserDto.cs @@ -63,6 +63,10 @@ public sealed class CreateUserRequest [MaxLength(256)] public string? DisplayName { get; set; } + /// Optional Neptun code. Must be empty, or unique across users. + [MaxLength(32)] + public string? NeptunCode { get; set; } + [Required] [MinLength(6)] public string Password { get; set; } = string.Empty; diff --git a/ahk-backend/Ahk.Web.Server/Admin/UsersAdminController.cs b/ahk-backend/Ahk.Web.Server/Admin/UsersAdminController.cs index 478f88c7..935c5407 100644 --- a/ahk-backend/Ahk.Web.Server/Admin/UsersAdminController.cs +++ b/ahk-backend/Ahk.Web.Server/Admin/UsersAdminController.cs @@ -108,11 +108,16 @@ public async Task> Get(int id, CancellationToken cancellat [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task> Create([FromBody] CreateUserRequest request, CancellationToken cancellationToken) { + var neptun = NormalizeNeptun(request.NeptunCode); + if (neptun is not null && await IsNeptunTakenAsync(neptun, excludeUserId: null, cancellationToken)) + return BadRequest(new { error = $"The Neptun code {neptun} is already assigned to another user." }); + var user = new ApplicationUser { UserName = request.UserName.Trim(), Email = string.IsNullOrWhiteSpace(request.Email) ? null : request.Email.Trim(), DisplayName = string.IsNullOrWhiteSpace(request.DisplayName) ? null : request.DisplayName.Trim(), + NeptunCode = neptun, EmailConfirmed = true, }; @@ -133,8 +138,12 @@ public async Task> Update(int id, [FromBody] UpdateUserReq if (user is null) return NotFound(); + var neptun = NormalizeNeptun(request.NeptunCode); + if (neptun is not null && await IsNeptunTakenAsync(neptun, excludeUserId: user.Id, cancellationToken)) + return BadRequest(new { error = $"The Neptun code {neptun} is already assigned to another user." }); + user.DisplayName = Trimmed(request.DisplayName); - user.NeptunCode = request.NeptunCode is null ? null : Normalize.Neptun(request.NeptunCode); + user.NeptunCode = neptun; var email = Trimmed(request.Email); if (!string.Equals(user.Email, email, StringComparison.OrdinalIgnoreCase)) @@ -307,4 +316,13 @@ private async Task LoadDtoAsync(ApplicationUser user, CancellationToken }; private static string? Trimmed(string? value) => string.IsNullOrWhiteSpace(value) ? null : value.Trim(); + + /// Canonical Neptun code, or null for a blank one — never "", so the filtered unique index treats + /// "no code" as absent rather than a shared value. + private static string? NormalizeNeptun(string? value) => + string.IsNullOrWhiteSpace(value) ? null : Normalize.Neptun(value); + + /// True when another user already holds this (already-normalized) Neptun code. + private Task IsNeptunTakenAsync(string neptun, int? excludeUserId, CancellationToken cancellationToken) => + db.Users.AnyAsync(u => u.NeptunCode == neptun && (excludeUserId == null || u.Id != excludeUserId), cancellationToken); } diff --git a/ahk-backend/Ahk.Web.Server/Ahk.Web.Server.csproj b/ahk-backend/Ahk.Web.Server/Ahk.Web.Server.csproj index 6da6e842..ed9b33e9 100644 --- a/ahk-backend/Ahk.Web.Server/Ahk.Web.Server.csproj +++ b/ahk-backend/Ahk.Web.Server/Ahk.Web.Server.csproj @@ -4,6 +4,13 @@ net10.0 enable enable + + true diff --git a/ahk-backend/Ahk.Web.Server/Auth/ExternalAuthController.cs b/ahk-backend/Ahk.Web.Server/Auth/ExternalAuthController.cs index 6c2c8a43..95d2c598 100644 --- a/ahk-backend/Ahk.Web.Server/Auth/ExternalAuthController.cs +++ b/ahk-backend/Ahk.Web.Server/Auth/ExternalAuthController.cs @@ -1,10 +1,12 @@ using System.Security.Claims; +using Ahk.Web.Data; using Ahk.Web.Data.Entities; using Ahk.Web.Server.Configuration; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Options; namespace Ahk.Web.Server.Auth; @@ -67,17 +69,23 @@ public async Task Callback([FromQuery] string? returnUrl) return Redirect(SafeReturnUrl(returnUrl)); } - // First time this external identity is seen: provision a local user and link the login. - var email = info.Principal.FindFirstValue(ClaimTypes.Email); + // First time this external identity is seen. Identify the person by Neptun code — the domain key — + // not by email/username, so an account an admin pre-provisioned with just a Neptun code is linked + // rather than duplicated. + var neptunClaim = info.Principal.FindFirstValue(BmeClaimTypes.NeptunCode); + var neptun = string.IsNullOrWhiteSpace(neptunClaim) ? null : Normalize.Neptun(neptunClaim); - var user = (email is not null ? await userManager.FindByEmailAsync(email) : null) - ?? new ApplicationUser { UserName = email ?? BuildUserName(info), EmailConfirmed = true }; + var user = neptun is null + ? null + : await userManager.Users.FirstOrDefaultAsync(u => u.NeptunCode == neptun); - ExternalClaimsMapper.SyncFromClaims(user, info.Principal); - - // Id is 0 until the row is inserted, so this distinguishes a brand-new user from one found by email. - if (user.Id == 0) + if (user is null) { + // No account carries this Neptun code (or the IdP sent none): provision a fresh local user. + var email = info.Principal.FindFirstValue(ClaimTypes.Email); + user = new ApplicationUser { UserName = email ?? BuildUserName(info), EmailConfirmed = true }; + ExternalClaimsMapper.SyncFromClaims(user, info.Principal); + var created = await userManager.CreateAsync(user); if (!created.Succeeded) { @@ -92,7 +100,10 @@ public async Task Callback([FromQuery] string? returnUrl) } else { - await userManager.UpdateAsync(user); + // Existing account matched by Neptun code (e.g. admin-created): attach this login to it. The + // username is never written by the claim sync, so it is preserved; email is refreshed. + if (ExternalClaimsMapper.SyncFromClaims(user, info.Principal)) + await userManager.UpdateAsync(user); } await userManager.AddLoginAsync(user, info); diff --git a/ahk-backend/Ahk.Web.Server/web.config b/ahk-backend/Ahk.Web.Server/web.config new file mode 100644 index 00000000..10fdb00e --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/web.config @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/ahk-frontend/src/app/api/api-client.ts b/ahk-frontend/src/app/api/api-client.ts index 72c6f532..8717eefd 100644 --- a/ahk-frontend/src/app/api/api-client.ts +++ b/ahk-frontend/src/app/api/api-client.ts @@ -3344,6 +3344,7 @@ export interface CreateUserRequest { userName: string; email?: string | undefined; displayName?: string | undefined; + neptunCode?: string | undefined; password: string; } diff --git a/ahk-frontend/src/app/features/admin/users/users.html b/ahk-frontend/src/app/features/admin/users/users.html index a2c4792e..2aea480e 100644 --- a/ahk-frontend/src/app/features/admin/users/users.html +++ b/ahk-frontend/src/app/features/admin/users/users.html @@ -39,6 +39,11 @@

Add local account

+
+ + + Optional. Must be unique; links an eduID login to this account. +
diff --git a/ahk-frontend/src/app/features/admin/users/users.ts b/ahk-frontend/src/app/features/admin/users/users.ts index 53fe80e7..a04ffbb8 100644 --- a/ahk-frontend/src/app/features/admin/users/users.ts +++ b/ahk-frontend/src/app/features/admin/users/users.ts @@ -51,6 +51,7 @@ export class AdminUsers implements OnInit { protected newUserName = ''; protected newEmail = ''; protected newDisplayName = ''; + protected newNeptun = ''; protected newPassword = ''; protected readonly showingRange = computed(() => { @@ -202,6 +203,7 @@ export class AdminUsers implements OnInit { userName: this.newUserName.trim(), email: this.newEmail.trim() || undefined, displayName: this.newDisplayName.trim() || undefined, + neptunCode: this.newNeptun.trim() || undefined, password: this.newPassword, }; @@ -224,6 +226,7 @@ export class AdminUsers implements OnInit { this.newUserName = ''; this.newEmail = ''; this.newDisplayName = ''; + this.newNeptun = ''; this.newPassword = ''; } From ffa871d2feadc2c082867e4d3c29f29d1cb7d1aa Mon Sep 17 00:00:00 2001 From: Bence Kovari Date: Thu, 30 Jul 2026 20:53:57 +0200 Subject: [PATCH 07/19] feat: enhance deployment workflow with new manifest handling and manual trigger options --- .claude/settings.json | 8 +- .github/workflows/ahk-web-deploy.yaml | 121 +++++++++++++++++++------ CLAUDE.md | 9 +- todo.md | 125 ++++++++++++++++++++++++++ 4 files changed, 235 insertions(+), 28 deletions(-) create mode 100644 todo.md diff --git a/.claude/settings.json b/.claude/settings.json index ebf3218e..721de38d 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -83,7 +83,13 @@ "Bash(rm -rf /tmp/ahk-webconfig-test && cd c:/Source/ahk-github-automation/ahk-backend && dotnet publish Ahk.Web.Server/Ahk.Web.Server.csproj -p:PublishProfile=Mezga -o /tmp/ahk-webconfig-test 2>&1 | tail -2 && echo \"=== published web.config ===\" && cat /tmp/ahk-webconfig-test/web.config)", "Bash(rm -rf /tmp/ahk-webconfig-test && echo cleaned)", "PowerShell(Get-NetTCPConnection -LocalPort 7443 -State Listen -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force }; \"backend stopped\")", - "PowerShell(Get-NetTCPConnection -LocalPort 7443 -State Listen -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force }; \"checked\")" + "PowerShell(Get-NetTCPConnection -LocalPort 7443 -State Listen -ErrorAction SilentlyContinue | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force }; \"checked\")", + "Bash(python -c \"import yaml; d=yaml.safe_load\\(open\\('.github/workflows/ahk-web-deploy.yaml'\\)\\); print\\('YAML OK'\\); print\\('inputs:', d['on']['workflow_dispatch']['inputs']\\)\")", + "Bash(awk '{print length\\($0\\)}')", + "Bash(where.exe rsync *)", + "Bash(wsl.exe rsync *)", + "Bash(wsl.exe -l -v)", + "Bash(wsl.exe bash -c ' *)" ], "additionalDirectories": [ "\\tmp" diff --git a/.github/workflows/ahk-web-deploy.yaml b/.github/workflows/ahk-web-deploy.yaml index f42e65a0..e5352bb7 100644 --- a/.github/workflows/ahk-web-deploy.yaml +++ b/.github/workflows/ahk-web-deploy.yaml @@ -1,7 +1,13 @@ name: AHK Web - Deploy to Mezga # Manual trigger only: this deploys to the on-prem IIS server behind the BME VPN. -on: [workflow_dispatch] +on: + workflow_dispatch: + inputs: + force_full: + description: "Ignore the stored deployment manifest and copy everything (use after a manual change on the server)" + type: boolean + default: false env: DOTNET_VERSION: "10.0.x" @@ -12,6 +18,10 @@ env: FRONTEND_DIR: ahk-frontend OFFLINE_PAGE: ahk-backend/Ahk.Web.Server/app_offline.htm MOUNT_POINT: /mnt/deploy + # Lives at the CIFS mount's root — a sibling of wwwroot/, the .exe and appsettings.json, never inside + # the ASP.NET Core app's own static-file root, so it is never web-reachable and never touched by the + # targeted copy/delete steps below. + MANIFEST_NAME: .deploy-manifest.sha256 jobs: deploy: @@ -63,9 +73,6 @@ jobs: mkdir -p publish/wwwroot cp -r ${{ env.FRONTEND_DIR }}/dist/ahk-frontend/browser/. publish/wwwroot/ - - name: Stage offline page alongside the publish output - run: cp ${{ env.OFFLINE_PAGE }} publish/app_offline.htm - - name: Generate idempotent migration script (artifact only — applied manually) run: | dotnet tool install --global dotnet-ef @@ -93,6 +100,11 @@ jobs: publish/appsettings.json > publish/appsettings.json.tmp mv publish/appsettings.json.tmp publish/appsettings.json + # Last content-mutating step before the diff: hashing anything after this point (e.g. re-injecting + # config) would make the manifest describe a tree that no longer matches what gets copied. + - name: Compute local deployment manifest + run: (cd publish && find . -type f -printf '%P\0' | sort -z | xargs -0 sha256sum) > new.manifest + # ---- D. VPN (SSTP) up ---- - name: Install SSTP client @@ -105,11 +117,6 @@ jobs: VPN_USER: ${{ vars.VPN_USER }} VPN_PASSWORD: ${{ secrets.VPN_PASSWORD }} run: | - # sstpc is a daemon that never returns. Background it AND redirect its stdout/stderr to a - # logfile: otherwise the backgrounded process keeps this step's output pipe open and the step - # hangs forever despite the '&'. No --cert-warn — the endpoint's cert validates against the - # system CA store. No 'defaultroute' — it is inert here (the runner's eth0 default wins), which - # is why internal traffic was not tunneled; the explicit host route in the next step handles it. sudo sstpc --log-stderr \ --user "$VPN_USER" --password "$VPN_PASSWORD" \ "$VPN_ADDRESS" \ @@ -131,16 +138,13 @@ jobs: env: VPN_ROUTES: ${{ vars.VPN_ROUTES }} run: | - # Split tunnel: only the configured internal hosts (e.g. mezga 152.66.188.8/32) go through - # ppp0. The runner->GitHub control channel and the public ahk.aut.bme.hu warm-up stay on the - # runner's default route. Automates the manual `ip route replace` from the first live run. for cidr in $VPN_ROUTES; do echo "Routing $cidr via ppp0" sudo ip route replace "$cidr" dev ppp0 done ip route show - # ---- E. Mount share, swap site ---- + # ---- E. Mount share, diff against last deploy, swap site ---- - name: Mount deployment share env: @@ -169,33 +173,100 @@ jobs: fi rm -f "$CREDS" + # Reads exactly one small file from the share — regardless of link speed this is fast, unlike + # reading file content to compare it (the actual reason the old rsync mirror was slow). + - name: Fetch previous deployment manifest + env: + FORCE_FULL: ${{ inputs.force_full }} + run: | + if [ "$FORCE_FULL" = "true" ]; then + echo "force_full requested — treating the stored manifest as empty (full re-copy)." + : > old.manifest + elif [ -f "$MOUNT_POINT/$MANIFEST_NAME" ]; then + cp "$MOUNT_POINT/$MANIFEST_NAME" old.manifest + else + echo "No manifest found on the share yet — treating this as a first-time full deploy." + : > old.manifest + fi + + # Pure local text processing — no network cost. sha256sum's format is 64 hex chars + two spaces + + # path, so "cut -c 67-" reliably extracts the path column regardless of spaces in a filename. + - name: Diff manifests + id: diff + run: | + sort old.manifest -o old.sorted + sort new.manifest -o new.sorted + + # Changed or added: whole lines (hash+path) present in the new build but not the old one — + # covers both "hash changed at an existing path" and "brand-new path". + comm -13 old.sorted new.sorted | cut -c 67- > changed.list + + # Removed: paths that existed before and are entirely absent from the new build — this is what + # correctly prunes Angular's abandoned content-hashed chunk files, unlike a size comparison. + cut -c 67- old.manifest | sort -u > old.paths + cut -c 67- new.manifest | sort -u > new.paths + comm -23 old.paths new.paths > removed.list + + changed=$(wc -l < changed.list) + removed=$(wc -l < removed.list) + echo "Changed/added: $changed, removed: $removed" + + if [ "$changed" -eq 0 ] && [ "$removed" -eq 0 ]; then + echo "has_changes=false" >> "$GITHUB_OUTPUT" + else + echo "has_changes=true" >> "$GITHUB_OUTPUT" + fi + - name: Stop site (drop app_offline.htm) + if: steps.diff.outputs.has_changes == 'true' run: | cp "$OFFLINE_PAGE" "$MOUNT_POINT/app_offline.htm" - # Give IIS a moment to notice and release file locks before mirroring. + # Give IIS a moment to notice and release file locks before copying. sleep 5 - - name: Mirror new files (keep app_offline.htm) + # Copies exactly the changed/added files (preserving their relative subdirectories) and deletes + # exactly the removed ones. --ignore-times/--whole-file/--inplace stop rsync from doing any of its + # own (CIFS-costly) comparison or delta-transfer logic — we already know these files need moving. + - name: Apply changed files + if: steps.diff.outputs.has_changes == 'true' run: | - ok=0 - for i in $(seq 1 10); do - if rsync -a --delete --exclude 'app_offline.htm' publish/ "$MOUNT_POINT/"; then - ok=1; break + if [ -s changed.list ]; then + ok=0 + for i in $(seq 1 10); do + if rsync -R --files-from=changed.list --ignore-times --whole-file --inplace \ + --no-perms --no-owner --no-group --no-times publish/ "$MOUNT_POINT/"; then + ok=1; break + fi + echo "rsync attempt $i failed (likely a locked file); retrying..." + sleep 2 + done + if [ "$ok" -ne 1 ]; then + echo "::error::Copying changed files failed after retries" + exit 1 fi - echo "rsync attempt $i failed (likely a locked file); retrying..." - sleep 2 - done - if [ "$ok" -ne 1 ]; then - echo "::error::Mirroring the deployment failed after retries" - exit 1 + fi + + if [ -s removed.list ]; then + while IFS= read -r path; do + rm -f "$MOUNT_POINT/$path" + done < removed.list fi - name: Wake site (remove app_offline.htm) + if: steps.diff.outputs.has_changes == 'true' run: rm -f "$MOUNT_POINT/app_offline.htm" - name: Warm up and verify run: curl --fail --show-error --retry 5 --retry-delay 3 https://ahk.aut.bme.hu/ + # Last content-mutating step, and only reached after the copy/delete above succeeded. A run that + # fails partway leaves the OLD manifest in place, so the next run still sees those files as + # "changed" and retries them — a failed run can only ever under-count what's already been done, + # never understate future work. + - name: Publish new deployment manifest + if: steps.diff.outputs.has_changes == 'true' + run: cp new.manifest "$MOUNT_POINT/$MANIFEST_NAME" + # ---- F. Teardown (always) ---- - name: Unmount share diff --git a/CLAUDE.md b/CLAUDE.md index 0b6ccadb..99df1134 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -43,7 +43,7 @@ Key integration contracts (keep these in sync when changing either side): Replaces the per-course Azure Function deployments with one site whose domain data is assigned to **Courses** (each course = what used to be a separate deployment, e.g. `viaubc01`). This is **not** multitenant isolation — it's course-scoped data with membership-based authorization. -- **ahk-backend** — ASP.NET Core **.NET 10** (`Ahk.Web.sln`). Layering: `Ahk.Web.Server` (controllers/middleware/auth, thin) → `Ahk.Web.Services` (domain logic) → `Ahk.Web.Data` (EF Core + **MSSQL**, Identity, migrations, seeder, `Normalize`). `Ahk.Web.Import` is a **throwaway** Cosmos-JSON→MSSQL console importer that references Data directly and **bypasses Services** (bulk movement, not domain ops). Tests in `Ahk.Web.Server.Tests` (xUnit + Moq). +- **ahk-backend** — ASP.NET Core **.NET 10** (`Ahk.Web.slnx`). Layering: `Ahk.Web.Server` (controllers/middleware/auth, thin) → `Ahk.Web.Services` (domain logic) → `Ahk.Web.Data` (EF Core + **MSSQL**, Identity, migrations, seeder, `Normalize`). `Ahk.Web.Import` is a **throwaway** Cosmos-JSON→MSSQL console importer that references Data directly and **bypasses Services** (bulk movement, not domain ops). Tests in `Ahk.Web.Server.Tests` (xUnit + Moq). - **No repository layer** — `DbContext` is already Unit of Work + repository. The legacy Cosmos repositories exist only because Cosmos has no composable LINQ context; that reason is gone. - **ahk-frontend** — **Angular 21** SPA (standalone components + signals). API clients/DTOs under `src/app/api/` are **NSwag-generated** from the backend's OpenAPI doc — never hand-edit them. @@ -56,6 +56,7 @@ Design decisions (rationale in the architecture plan and `ahk-backend/README.md` - **No `end_session_endpoint`** is advertised, so logout is local-only; `POST /api/auth/logout` returns `{endSessionUrl}` (null today) and the SPA navigates there if set. - `OpenIdConnectOptions` ships **only `DeleteClaim` actions** — claims arriving from the *userinfo* endpoint (BME sends `email`, `name`, `neptun_code`, `eduperson_scoped_affiliation` there) are silently dropped unless explicitly mapped in `Program.cs`. - Persisted onto `ApplicationUser`: `NeptunCode` and `Affiliation` (multi-valued, joined with `;`), re-synced on every login by `Auth/ExternalClaimsMapper.cs`. + - **eduID identifies a user by Neptun code, not email/username.** `ApplicationUser.NeptunCode` is filtered-unique (blank stored as null, may repeat; any value unique). First OIDC login matches an existing account by Neptun and links the external login, so an admin-pre-created account is never duplicated (`ExternalAuthController`). Admin create/update enforce the same rule (blank→null, else `Normalize.Neptun`, 400 on clash). eduID **always refreshes email**; the claim sync never writes username. - The client secret is never in config — `dotnet user-secrets` locally, `Authentication__Oidc__ClientSecret` in production. - **Dev mock OIDC provider** (`Ahk.Web.Server/MockOidc/`): only the production redirect URI is registered with BME, so localhost cannot use the real IdP. Enabled by `Authentication:Oidc:UseMockProvider` in Development; serves discovery/authorize/token/userinfo/JWKS at `/mock-oidc` and issues **genuinely signed** RS256 id_tokens so the real validation path runs. Switch persona with `GET /mock-oidc/persona?user=instructor|student|noclaims`. - **Course scoping**: path segment `/api/{course}/...`; `CourseResolutionMiddleware` resolves the `Course` and an `ICurrentCourseProvider` drives an EF Core global query filter over `ICourseScoped` entities; the `CourseMember` authorization policy gates access. Host/admin routes live under `/api/admin/...`. Machine-to-machine endpoints (webhooks / CI callbacks, added during the port) will resolve their course from the payload/token, **not** the path segment. @@ -132,9 +133,13 @@ npm run generate-api # regenerate src/app/api from the backend's OpenAPI (back - **No Docker in this environment** — dev dependencies are built in-app (e.g. the mock OIDC provider), not containerized. - **Verify UI changes by screenshotting the running app**, not by trusting the build. Chrome is at `/c/Program Files/Google/Chrome/Application/chrome.exe`. A plain `--headless=new --screenshot` fires before Angular hydrates and yields a near-empty page — add `--virtual-time-budget=4000`. For screens behind login, start Chrome with `--remote-debugging-port=9222` and drive the DevTools protocol from a Node script: Node 24 ships a built-in `WebSocket`, so this needs no npm dependency. Always pass `--ignore-certificate-errors` (self-signed dev cert). - **No image tooling** — no PIL, no ImageMagick. To read a PNG's pixels (sampling a brand colour, checking dimensions) decode it by hand with `zlib` + `struct`. EPS files are text-ish: `%%CMYKCustomColor` in the header carries the print colour spec. +- **Prod hosting is same-origin**: the backend serves the Angular SPA — `UseDefaultFiles`/`UseStaticFiles` + `MapFallbackToFile("index.html")` in `Program.cs`, `ng build` output copied into `wwwroot`. Only dev uses the proxy. +- **`web.config` is checked in with its SDK transform disabled** (`IsTransformWebConfigDisabled=true`): Mezga registers ANCM under the **V1** name `AspNetCoreModule`, so the SDK-generated V2 web.config fails to start the app there. Don't delete the file or re-enable the transform. +- **`SelfContained=true` needs a `RuntimeIdentifier`** — pinned to `win-x64` in `Mezga.pubxml`; the server has no .NET runtime. ### CI `.github/workflows/*-build.yaml` build+test each app (path-filtered so only the changed app runs). `*-azure-publish.yaml` / `*-docker-publish.yaml` deploy. Several azure-publish workflows are per-instance (e.g. `VIAUBC01`, `viaubb01`) — deployments are duplicated per course/organization instance. +The portal has its own `ahk-web-deploy.yaml` (manual `workflow_dispatch`): publishes self-contained `win-x64` via the `Mezga.pubxml` profile, tunnels to the on-prem IIS server **Mezga** over **SSTP VPN**, mirrors the build over a CIFS share (`rsync`, `app_offline.htm` bracketing). Migrations are **not** auto-applied — CI emits an idempotent `migrate.sql` artifact applied by hand to a fresh DB. ## github-monitor architecture (the most complex app) @@ -159,5 +164,5 @@ npm run generate-api # regenerate src/app/api from the backend's OpenAPI (back - **Portal look is the BME AUT identity**, derived from aut.bme.hu — crimson Georgia headings, Verdana body, parchment (`#dbd9c0`) table headers, the department logo. Type does three jobs: `--font-display` (Georgia) for headings, `--font-ui` (Verdana) for labels/controls, `--font-mono` for machine identifiers (slugs, orgs, repos, Neptun codes, tokens) — do not "unify" them. `--brand` (`#a4001e`, headings + primary actions), `--link` (`#074371` navy, navigation) and `--bad` (`#801b1b`, broken) are **three deliberately different reds**; collapsing them loses meaning. The logo masters and every colour's provenance live in `ahk-frontend/brand/` (BME AUT identity pack + the eduID login logo); the web copies the app loads are in `ahk-frontend/public/`. No square favicon exists yet (the mark is 2.86:1); a follow-up needs a square crop from the EPS. The **login screen leads with eduID** (the federated `/api/auth/external/challenge` flow); local username/password is collapsed behind an "I don't have an eduID account" link. The eduID button follows the [eduID brand](https://eduid.hu/hu/depo/) but renders its own English "Login" rather than the official Hungarian-label PNG; `--eduid` blue is scoped to that button, never in the global palette. - **Portal code style**: **no top-level statements** (`Program` is an explicit class with `Main`); **`int` keys everywhere**, including Identity (`IdentityUser`); the domain term is **Course**, never "tenant". - **Frontend API errors**: use `readApiError(err, fallback)` from `ahk-frontend/src/app/core/api-error.ts` instead of parsing a `SwaggerException` inline. It pulls out the API's own `{error}`/`{errors}` message and reports status 0 as "the server is not responding" — without that, a generated-client failure surfaces as a misleading domain error (a stopped backend once looked exactly like "wrong password"). -- **Portal tests**: course-scoping is tested against `ApplicationDbContext` directly with EF InMemory + a mutable `ICurrentCourseProvider` double. `WebApplicationFactory` DbContext swaps must remove **both** `DbContextOptions` and EF 9+'s `IDbContextOptionsConfiguration` descriptors, else two providers register. `Ahk.Web.Services` exposes internals via `InternalsVisibleTo`. Frontend single run: `npx ng test --watch=false`. +- **Portal tests**: course-scoping is tested against `ApplicationDbContext` directly with EF InMemory + a mutable `ICurrentCourseProvider` double. `WebApplicationFactory` DbContext swaps must remove **both** `DbContextOptions` and EF 9+'s `IDbContextOptionsConfiguration` descriptors, else two providers register. `Ahk.Web.Services` exposes internals via `InternalsVisibleTo`. Frontend single run: `npx ng test --watch=false`. Controller tests can run over a real `UserManager` on EF InMemory (see `UserNeptunTests`) — but InMemory does **not** enforce filtered unique indexes, so uniqueness is proven via the controller's pre-check, not the DB. - **Legacy parity is a hard constraint when porting**: grade semantics (append-only, positional `ex0`/`ex1` name carry-forward, per-exercise summing) and the CSV layout are covered by parity tests — changing them changes existing courses' grades. One deliberate deviation: `CsvExporter` sorts columns `Ordinal` rather than culture-sensitively. diff --git a/todo.md b/todo.md new file mode 100644 index 00000000..7b1ebe2b --- /dev/null +++ b/todo.md @@ -0,0 +1,125 @@ +# AHK portal — review findings + +Whole-app review (ahk-backend + ahk-frontend, cross-checked against the four legacy apps and the +docs). Review only — nothing in this list has been fixed. Grouped by category, each item names the +file(s) involved. Severity is my judgment of impact, not a promise. + +--- + +## 1. Missing / not-yet-ported functionality + +These are gaps versus the legacy system's functional scope, beyond what CLAUDE.md already summarizes +as "the write-side entry points." + +1. **No GitHub webhook receiver.** Nothing in `Ahk.Web.Server` maps `/api/integrations/github` (the + path `docs/github-app.md` reserves for it). Every rule `github-monitor` enforces today — branch + protection, single-open-PR, reviewer-must-be-assignee, comment-edit/delete tracking, the 5-run + Actions cap — has **zero equivalent** in the portal. `CourseGitHubConfig.WorkflowRunThreshold` is + stored and editable in the admin UI but **nothing reads it** — grep confirms no consumer. A course + migrated to the portal today silently loses all of this enforcement. +2. **No `/ahk ok` chatops**, and therefore: +3. **No way to enter or override a grade through the portal at all**, not even manually. `IGradeService` + (`Ahk.Web.Services/Grading/GradeService.cs`) is fully implemented — `SetGradeAsync`, + `ConfirmAutoGradeAsync`, `RecordEvaluationResultAsync` — but grep across `Ahk.Web.Server` finds + **no controller calling any of them**. Today's admin/instructor UI can only *read* grades + (`GradesController`), never write one. Worth deciding whether a stopgap manual-entry admin endpoint + is wanted before the chatops port lands, since courses may move to the portal before that ships. +4. **No HMAC-verified CI callback** (the `publish-results-pr` → grade-management webhook). CI callback + *tokens* are fully manageable (`CoursesAdminController` CRUD, `WebhookTokenService`, + `CiCallbackTokenHealthCheck`), but nothing accepts a signed payload and calls + `RecordEvaluationResultAsync`. So even the automated-evaluation path has no landing point yet. +5. **Root `README.md` never mentions the portal.** It describes only the four legacy apps; a newcomer + reading it has no idea `ahk-backend`/`ahk-frontend` exist. (See also §5.) + +## 2. Correctness / code-quality findings + +1. **`POST /api/auth/register` is a live, unauthenticated, unguarded endpoint** — + [AuthController.cs:99-111](ahk-backend/Ahk.Web.Server/Auth/AuthController.cs#L99-L111). Anyone can + create a full local account with any username/password, no admin approval, no email verification, + no Neptun code. The SPA never calls it (`login.ts`'s own comment: "local username/password is for + the handful of administrator-issued accounts") — grep across the frontend confirms only + `UsersAdminController.Create` (admin-gated) is used for account creation. This directly contradicts + the documented access model and is reachable by anyone who can reach the API. Recommend removing the + endpoint or gating it behind `[Authorize(Roles = Admin)]`. +2. **`GitHubUsername` is existence-checked, not ownership-verified, and not unique** — + [ProfileController.cs](ahk-backend/Ahk.Web.Server/Auth/ProfileController.cs) calls + `GET /users/{login}` to confirm the login exists, but nothing proves the caller actually controls + that GitHub account (no OAuth/device-flow proof), and `ApplicationUser.GitHubUsername`/ + `GitHubUserId` have no unique index (confirmed by grepping `ApplicationDbContext.cs` — only + `MaxLength`, no `HasIndex`). Concretely: user B can claim a string that happens to be real user + Alice's GitHub login. When B accepts an assignment, `AssignmentInviteService.AcceptAsync` calls + `AddCollaboratorAsync(..., login: user.GitHubUsername!, ...)`, which invites/adds **Alice's real + GitHub account** as a collaborator on B's own private homework repo — an unwanted invite sent to a + stranger, and a spoofing vector worth deciding whether to close (verify via OAuth, or at minimum add + a unique index so only one site account can claim a given GitHub login). +3. **TOCTOU race in repository creation** — + [AssignmentInviteService.cs:164-172](ahk-backend/Ahk.Web.Services/Assignments/AssignmentInviteService.cs#L164-L172). + `AcceptAsync` checks `GetRepositoryAsync` for an existing repo, then calls + `GenerateFromTemplateAsync` if none is found. Two concurrent accept requests (double-click, two + tabs) can both observe "not found" and both call `generate`; GitHub's second call would 422 ("name + already exists"), which is an unhandled `GitHubOperationException` → 500 for the loser. The DB-level + protection (unique index on `(AssignmentId, UserId)`) only catches the *second SaveChanges*, not this + earlier GitHub-side race. Low likelihood, but worth a comment or a catch-and-retry. +4. **`SaveAssignmentRequest.TemplateRepoName` isn't validated for the `owner/name` shape** — + [AssignmentsController.cs:177-184](ahk-backend/Ahk.Web.Server/Courses/AssignmentsController.cs#L177-L184) + only checks non-empty. `IAssignmentService.SplitRepoName` (`AssignmentService.cs:53-61`) silently + treats a slash-less value as `(owner: "", name: fullName)` rather than rejecting it. A typo'd + template name (e.g. missing the org prefix) is accepted at Create time and only fails later, either + when a student accepts (GitHub call with an empty owner) or when the instructor opts into + `checkTemplate=true`. Consider validating the shape at Create/Update instead. +5. **No `UseExceptionHandler`/`UseHsts` in `Program.cs`** — grep of `ConfigurePipelineAsync` shows + neither is registered for any environment. Worth confirming deliberately (e.g. relying on IIS/ANCM + defaults in production) rather than by omission, since an unhandled exception's exact response shape + in Production hasn't been verified either way in this review. + +## 3. Test coverage gaps + +1. **`ExternalAuthController`'s Neptun-matching logic has no test at all.** Grepping + `Ahk.Web.Server.Tests` for `ExternalAuthController` finds only compiled binaries, no source + reference. This is the controller changed this session to link eduID logins by Neptun code instead + of email — exactly the kind of logic where a regression would silently duplicate or misattribute + user accounts, and it's currently unverified by any automated test. `ExternalClaimsMapperTests` + covers claim projection only, not the lookup/link/create branching in `Callback`. +2. No test exercises `CoursesAdminController.Delete`'s explicit multi-table cascade + (`ExecuteDeleteAsync` for grade points → grades → events → submissions → acceptances → assignments) + against a course that actually has rows in all of those tables. The logic reads correctly by + inspection, but CLAUDE.md flags this exact area as fragile ("a new course-scoped entity whose FK is + NoAction must be added to that list, or the delete fails") — a regression test would catch the next + entity that's added without updating the list. + +## 4. Documentation issues + +1. **Dangling reference to "the architecture plan."** Both `CLAUDE.md` and `ahk-backend/README.md` + reference "the architecture plan" for design rationale (OIDC choices, `MapIdentityApi` rejection, + etc.), but no such file exists anywhere in the repo — confirmed by searching for the phrase across + the whole tree. Either the document exists somewhere outside this repo and should be linked, or the + references should point at wherever the rationale actually now lives (much of it is duplicated + inline in CLAUDE.md already). +2. **Root `README.md` describes only the four legacy apps** and does not mention `ahk-backend`/ + `ahk-frontend` or that a migration is underway — see §1 item 5. A one-paragraph pointer to + `ahk-backend/README.md` would close this. +3. `ahk-backend/README.md`'s "Run" section has no mention of the new `ahk-web-deploy.yaml` production + deployment path (SSTP VPN / CIFS / Mezga) added this session — it's only in the root `CLAUDE.md`. + Minor, but a reader of just the backend README would not find it. + +## 5. Deployment / operational open items (from this session's work, not yet fully closed) + +1. **Local dev databases still hold the old 5-migration history.** The `Migrations/` directory was + reset to a single `InitialCreate` this session (for a clean production rollout). Any existing dev + LocalDB will conflict on `dotnet ef database update` (its `__EFMigrationsHistory` references + migration ids that no longer exist). Needs a drop/recreate before next use — already called out + verbally, tracking here so it isn't lost. +2. **The CIFS mount fix (credentials file instead of inline `-o password=`) has not yet been confirmed + against a real deploy run.** It was applied to fix a `mount error(13)` diagnosed from symptoms + (likely a comma in the password truncating the inline option), but the next live workflow run is the + first real confirmation. +3. **`VPN_CA_CERT` support was added then the user reported it unnecessary** (the endpoint's cert + validates fine); the plan says to drop the block entirely, but worth double-checking the final + workflow file has no leftover dead branch for it. +4. **`ahk-web-deploy.yaml` has never completed an end-to-end green run** (build → test → VPN → mount → + mirror → web.config-driven app start → warm-up) in one pass, only fixed incrementally per failure. + Worth one full run start-to-finish as a final confidence check before calling the pipeline done. + +--- + +*Compiled from a manual review; no source files were modified as part of this pass.* From 7482b3dc6b84d6be2c896e851faea2066357ea1f Mon Sep 17 00:00:00 2001 From: Bence Kovari Date: Wed, 5 Aug 2026 02:13:50 +0200 Subject: [PATCH 08/19] feat: add advisory template check for assignment creation - Implemented CheckTemplate endpoint in AssignmentsController for real-time validation of template repository names during assignment creation. - Added CheckTemplateRequest DTO to facilitate the request structure. - Updated AssignmentsClient to include checkTemplate method for API interaction. - Enhanced CourseAssignments component to verify template status after assignment save, displaying any issues to the user. - Introduced a new GitHub setup help page for guiding users through GitHub App registration and configuration. - Improved UI in course editor and user management sections, including password generation and token management features. --- .claude/settings.json | 15 +- .../Admin/CoursesAdminController.cs | 15 +- .../Courses/AssignmentsController.cs | 17 + .../Courses/Dto/AssignmentDto.cs | 10 + .../Courses/WebhookTokenService.cs | 10 +- ahk-frontend/src/app/api/api-client.ts | 60 ++++ ahk-frontend/src/app/app.routes.ts | 4 + .../features/admin/courses/course-editor.html | 29 +- .../features/admin/courses/course-editor.scss | 16 + .../features/admin/courses/course-editor.ts | 35 ++ .../app/features/admin/help/github-setup.html | 305 ++++++++++++++++++ .../app/features/admin/help/github-setup.scss | 77 +++++ .../app/features/admin/help/github-setup.ts | 28 ++ .../src/app/features/admin/users/users.html | 27 +- .../src/app/features/admin/users/users.scss | 15 + .../src/app/features/admin/users/users.ts | 44 +++ .../course/assignments/assignments.html | 46 +-- .../course/assignments/assignments.ts | 37 ++- ahk-frontend/src/app/layout/shell/shell.html | 2 + 19 files changed, 740 insertions(+), 52 deletions(-) create mode 100644 ahk-frontend/src/app/features/admin/help/github-setup.html create mode 100644 ahk-frontend/src/app/features/admin/help/github-setup.scss create mode 100644 ahk-frontend/src/app/features/admin/help/github-setup.ts diff --git a/.claude/settings.json b/.claude/settings.json index 721de38d..f96cc89f 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -89,10 +89,21 @@ "Bash(where.exe rsync *)", "Bash(wsl.exe rsync *)", "Bash(wsl.exe -l -v)", - "Bash(wsl.exe bash -c ' *)" + "Bash(wsl.exe bash -c ' *)", + "Bash(npm start *)", + "Bash(node shot.mjs)", + "Read(//c/Users/beny314/AppData/Local/Temp/claude/c--Source-ahk-github-automation/f74052ba-9e93-4760-8fe5-7c53f23ddecb/scratchpad/**)", + "Bash(sed 's#/admin/help/github?org=ahk-viaubc01#/admin/courses/1#; s/help-page.png/course-editor.png/' shot.mjs)", + "Bash(node shot2.mjs)", + "PowerShell(foreach \\($port in 7443,4200\\) { try { Get-NetTCPConnection -LocalPort $port -State Listen -ErrorAction Stop | Select-Object -ExpandProperty OwningProcess -Unique | ForEach-Object { Stop-Process -Id $_ -Force -ErrorAction SilentlyContinue } } catch {} }; Write-Output \"stopped\")", + "Bash(node -e \"const {readFileSync}=require\\('fs'\\); const b=readFileSync\\('help-page.png'\\); console.log\\('png bytes:', b.length\\);\")", + "Bash(node shot3.mjs)", + "PowerShell(try { Get-NetTCPConnection -LocalPort 7443 -State Listen -ErrorAction Stop | Select-Object -ExpandProperty OwningProcess -Unique | ForEach-Object { Stop-Process -Id $_ -Force -ErrorAction SilentlyContinue } } catch {}; Write-Output \"backend stopped\")", + "Bash(node shot4.mjs)" ], "additionalDirectories": [ - "\\tmp" + "\\tmp", + "C:\\Users\\beny314\\AppData\\Local\\Temp\\claude\\c--Source-ahk-github-automation\\f74052ba-9e93-4760-8fe5-7c53f23ddecb\\scratchpad" ] }, "enabledPlugins": { diff --git a/ahk-backend/Ahk.Web.Server/Admin/CoursesAdminController.cs b/ahk-backend/Ahk.Web.Server/Admin/CoursesAdminController.cs index b5798aed..47692e7f 100644 --- a/ahk-backend/Ahk.Web.Server/Admin/CoursesAdminController.cs +++ b/ahk-backend/Ahk.Web.Server/Admin/CoursesAdminController.cs @@ -97,7 +97,7 @@ public async Task> Get(int id, CancellationToken c SubmissionCount = await db.Submissions.IgnoreQueryFilters().CountAsync(s => s.CourseId == id, cancellationToken), GitHubConfig = ToDto(course.GitHubConfig), Members = members, - WebhookTokens = tokens.Select(t => ToDto(t, includeSecret: false)).ToList(), + WebhookTokens = tokens.Select(ToDto).ToList(), }); } @@ -305,10 +305,10 @@ public async Task RemoveMember(int id, int userId, CancellationTo public async Task>> ListTokens(int id, CancellationToken cancellationToken) { var tokens = await webhookTokens.ListForCourseAsync(id, cancellationToken); - return Ok(tokens.Select(t => ToDto(t, includeSecret: false)).ToList()); + return Ok(tokens.Select(ToDto).ToList()); } - /// Issues a token. The response is the only place its secret appears. + /// Issues a token, returning its secret. The secret is also readable later via the list endpoint. [HttpPost("{id:int}/tokens")] [ProducesResponseType(typeof(WebhookTokenDto), StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status404NotFound)] @@ -318,7 +318,7 @@ public async Task> CreateToken(int id, [FromBody] return NotFound(); var token = await webhookTokens.CreateAsync(id, Trimmed(request.Description), cancellationToken); - return CreatedAtAction(nameof(ListTokens), new { id }, ToDto(token, includeSecret: true)); + return CreatedAtAction(nameof(ListTokens), new { id }, ToDto(token)); } [HttpDelete("{id:int}/tokens/{tokenId:int}")] @@ -357,11 +357,14 @@ public async Task RevokeToken(int id, int tokenId, CancellationTo private static string? Hint(string? secret) => string.IsNullOrEmpty(secret) || secret.Length < 8 ? null : secret[^4..]; - private static WebhookTokenDto ToDto(CourseWebhookToken token, bool includeSecret) => new() + // The CI callback secret is a plaintext column (the HMAC scheme needs the raw key), and every token endpoint + // here is admin-only. An admin who can mint a token can already obtain a working secret, so returning an + // existing one is no extra exposure — it lets the console copy a secret again rather than force a re-issue. + private static WebhookTokenDto ToDto(CourseWebhookToken token) => new() { Id = token.Id, Token = token.Token, - Secret = includeSecret ? token.Secret : null, + Secret = token.Secret, Description = token.Description, CreatedAt = token.CreatedAt, RevokedAt = token.RevokedAt, diff --git a/ahk-backend/Ahk.Web.Server/Courses/AssignmentsController.cs b/ahk-backend/Ahk.Web.Server/Courses/AssignmentsController.cs index c69dbeb2..56ff38f7 100644 --- a/ahk-backend/Ahk.Web.Server/Courses/AssignmentsController.cs +++ b/ahk-backend/Ahk.Web.Server/Courses/AssignmentsController.cs @@ -61,6 +61,23 @@ public async Task> Get(int id, [FromQuery] boo }); } + /// + /// Advisory template check for a repository name the editor is still typing, before the assignment is saved. + /// Same GitHub lookup as 's checkTemplate, but keyed on a name rather than a stored + /// assignment — so the check is available while creating, not only while editing. Never blocks anything. + /// + [HttpPost("check-template")] + [ProducesResponseType(typeof(TemplateCheckDto), StatusCodes.Status200OK)] + public async Task> CheckTemplate([FromBody] CheckTemplateRequest request, CancellationToken cancellationToken) + { + ArgumentNullException.ThrowIfNull(request); + + var course = CurrentCourse(); + var check = await assignments.CheckTemplateAsync(course.Id, request.TemplateRepoName ?? string.Empty, cancellationToken); + + return Ok(TemplateCheckDto.From(check)); + } + [HttpPost] [ProducesResponseType(typeof(AssignmentDto), StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status400BadRequest)] diff --git a/ahk-backend/Ahk.Web.Server/Courses/Dto/AssignmentDto.cs b/ahk-backend/Ahk.Web.Server/Courses/Dto/AssignmentDto.cs index e8ee2fb4..4a840778 100644 --- a/ahk-backend/Ahk.Web.Server/Courses/Dto/AssignmentDto.cs +++ b/ahk-backend/Ahk.Web.Server/Courses/Dto/AssignmentDto.cs @@ -77,6 +77,16 @@ public sealed class SaveAssignmentRequest public string TemplateRepoName { get; set; } = string.Empty; } +/// +/// A template repository to look up on GitHub without saving an assignment first — lets the editor validate +/// a name while creating, before an assignment id exists. A body (not a query param) because the name may +/// contain a '/'. +/// +public sealed class CheckTemplateRequest +{ + public string? TemplateRepoName { get; set; } +} + /// One student's acceptance, as the instructor's roster of an assignment shows it. public sealed class AssignmentAcceptanceDto { diff --git a/ahk-backend/Ahk.Web.Services/Courses/WebhookTokenService.cs b/ahk-backend/Ahk.Web.Services/Courses/WebhookTokenService.cs index 155eb88b..b4062e06 100644 --- a/ahk-backend/Ahk.Web.Services/Courses/WebhookTokenService.cs +++ b/ahk-backend/Ahk.Web.Services/Courses/WebhookTokenService.cs @@ -9,13 +9,13 @@ public interface IWebhookTokenService { Task GetSecretForTokenAsync(string token, CancellationToken cancellationToken = default); - /// Lists a course's tokens, newest first. Secrets are not returned — they are shown once, at creation. - Task> ListForCourseAsync(int courseId, CancellationToken cancellationToken = default); - /// - /// Issues a new token/secret pair for a course. The returned entity carries the plaintext secret; it is the - /// only time the caller can show it, so the admin UI surfaces it immediately. + /// Lists a course's tokens, newest first, including the plaintext secret. Every caller is an admin who could + /// mint an equivalent token anyway, so the console can copy an existing secret rather than re-issue. /// + Task> ListForCourseAsync(int courseId, CancellationToken cancellationToken = default); + + /// Issues a new token/secret pair for a course. The returned entity carries the plaintext secret. Task CreateAsync(int courseId, string? description, CancellationToken cancellationToken = default); /// Revokes a token so callbacks signed with it are rejected. Returns false when it does not exist. diff --git a/ahk-frontend/src/app/api/api-client.ts b/ahk-frontend/src/app/api/api-client.ts index 8717eefd..1986a106 100644 --- a/ahk-frontend/src/app/api/api-client.ts +++ b/ahk-frontend/src/app/api/api-client.ts @@ -303,6 +303,7 @@ export interface IAssignmentsClient { get(id: number, course: string, checkTemplate?: boolean | undefined): Observable; update(id: number, request: SaveAssignmentRequest, course: string): Observable; delete(id: number, course: string): Observable; + checkTemplate(request: CheckTemplateRequest, course: string): Observable; archive(id: number, course: string): Observable; unarchive(id: number, course: string): Observable; regenerateInvite(id: number, course: string): Observable; @@ -635,6 +636,61 @@ export class AssignmentsClient implements IAssignmentsClient { return _observableOf(null as any); } + checkTemplate(request: CheckTemplateRequest, course: string): Observable { + let url_ = this.baseUrl + "/api/{course}/assignments/check-template"; + if (course === undefined || course === null) + throw new globalThis.Error("The parameter 'course' must be defined."); + url_ = url_.replace("{course}", encodeURIComponent("" + course)); + url_ = url_.replace(/[?&]$/, ""); + + const content_ = JSON.stringify(request); + + let options_ : any = { + body: content_, + observe: "response", + responseType: "blob", + withCredentials: true, + headers: new HttpHeaders({ + "Content-Type": "application/json", + "Accept": "application/json" + }) + }; + + return this.http.request("post", url_, options_).pipe(_observableMergeMap((response_ : any) => { + return this.processCheckTemplate(response_); + })).pipe(_observableCatch((response_: any) => { + if (response_ instanceof HttpResponseBase) { + try { + return this.processCheckTemplate(response_ as any); + } catch (e) { + return _observableThrow(e) as any as Observable; + } + } else + return _observableThrow(response_) as any as Observable; + })); + } + + protected processCheckTemplate(response: HttpResponseBase): Observable { + const status = response.status; + const responseBlob = + response instanceof HttpResponse ? response.body : + (response as any).error instanceof Blob ? (response as any).error : undefined; + + let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }} + if (status === 200) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + let result200: any = null; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as TemplateCheckDto; + return _observableOf(result200); + })); + } else if (status !== 200 && status !== 204) { + return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => { + return throwException("An unexpected server error occurred.", status, _responseText, _headers); + })); + } + return _observableOf(null as any); + } + archive(id: number, course: string): Observable { let url_ = this.baseUrl + "/api/{course}/assignments/{id}/archive"; if (id === undefined || id === null) @@ -3111,6 +3167,10 @@ export interface TemplateCheckDto { problem?: string | undefined; } +export interface CheckTemplateRequest { + templateRepoName?: string | undefined; +} + export interface SaveAssignmentRequest { name?: string; description?: string | undefined; diff --git a/ahk-frontend/src/app/app.routes.ts b/ahk-frontend/src/app/app.routes.ts index ccb0dad2..993bcc85 100644 --- a/ahk-frontend/src/app/app.routes.ts +++ b/ahk-frontend/src/app/app.routes.ts @@ -39,6 +39,10 @@ export const routes: Routes = [ path: 'health', loadComponent: () => import('./features/admin/health/health').then((m) => m.AdminHealth), }, + { + path: 'help/github', + loadComponent: () => import('./features/admin/help/github-setup').then((m) => m.GitHubSetupHelp), + }, { path: '', pathMatch: 'full', redirectTo: 'courses' }, ], }, diff --git a/ahk-frontend/src/app/features/admin/courses/course-editor.html b/ahk-frontend/src/app/features/admin/courses/course-editor.html index 4c9052e8..bea02443 100644 --- a/ahk-frontend/src/app/features/admin/courses/course-editor.html +++ b/ahk-frontend/src/app/features/admin/courses/course-editor.html @@ -101,6 +101,9 @@

Course settings

GitHub integration

Credentials this course uses to talk to GitHub. Stored values are never shown again.

+ + Setup guide +
@@ -221,7 +224,10 @@

CI callback tokens

@if (issuedToken(); as t) {
-

Token created. Copy the secret now — it is not shown again.

+

+ Token created. Its secret is shown here, and stays available — you can copy it again from the list + below at any time. +

Token
{{ t.token }}
@@ -246,7 +252,12 @@

CI callback tokens

@for (t of c.webhookTokens; track t.id) { - {{ t.token }} + + {{ t.token }} + @if (revealed().has(t.id ?? 0)) { +
{{ t.secret }}
+ } + {{ t.description || '—' }} {{ t.createdAt | date: 'yyyy-MM-dd' }} @@ -257,9 +268,17 @@

CI callback tokens

} - @if (!t.revokedAt) { - - } + + + + @if (!t.revokedAt) { + + } + } @empty { diff --git a/ahk-frontend/src/app/features/admin/courses/course-editor.scss b/ahk-frontend/src/app/features/admin/courses/course-editor.scss index 1d6bd616..945e524d 100644 --- a/ahk-frontend/src/app/features/admin/courses/course-editor.scss +++ b/ahk-frontend/src/app/features/admin/courses/course-editor.scss @@ -38,6 +38,22 @@ textarea { border-bottom: 1px solid var(--rule); } +/* Token row actions: keep the copy/show/revoke buttons spaced and right-aligned in the nowrap actions cell. */ +.token-actions { + display: inline-flex; + gap: 0.375rem; + justify-content: flex-end; +} + +/* The secret revealed under its token — smaller and dimmer than the token, and free to wrap. */ +.secret-reveal { + margin-top: 0.25rem; + font-size: 0.75rem; + color: var(--ink-2); + word-break: break-all; + white-space: normal; +} + .kv { display: grid; grid-template-columns: auto 1fr; diff --git a/ahk-frontend/src/app/features/admin/courses/course-editor.ts b/ahk-frontend/src/app/features/admin/courses/course-editor.ts index e56f949d..7fc88166 100644 --- a/ahk-frontend/src/app/features/admin/courses/course-editor.ts +++ b/ahk-frontend/src/app/features/admin/courses/course-editor.ts @@ -71,6 +71,10 @@ export class CourseEditor implements OnInit { protected newTokenDescription = ''; protected readonly issuedToken = signal(null); protected readonly creatingToken = signal(false); + /** Token id most recently copied, for transient "Copied" feedback. */ + protected readonly copiedTokenId = signal(null); + /** Token ids whose secret is currently revealed inline. */ + protected readonly revealed = signal>(new Set()); // ---- Staff ---- protected memberSearch = ''; @@ -242,6 +246,37 @@ export class CourseEditor implements OnInit { this.issuedToken.set(null); } + /** Copies a token's secret to the clipboard, with brief per-row "Copied" feedback. */ + protected copySecret(token: WebhookTokenDto): void { + const secret = token.secret; + if (!secret) { + return; + } + navigator.clipboard.writeText(secret).then( + () => { + this.copiedTokenId.set(token.id ?? null); + setTimeout(() => { + if (this.copiedTokenId() === token.id) { + this.copiedTokenId.set(null); + } + }, 1500); + }, + () => this.error.set('The secret could not be copied to the clipboard.'), + ); + } + + /** Reveals or hides a token's secret inline, so it can be read as well as copied. */ + protected toggleReveal(token: WebhookTokenDto): void { + const id = token.id ?? 0; + const next = new Set(this.revealed()); + if (next.has(id)) { + next.delete(id); + } else { + next.add(id); + } + this.revealed.set(next); + } + // ---- Staff ---- protected searchUsers(): void { diff --git a/ahk-frontend/src/app/features/admin/help/github-setup.html b/ahk-frontend/src/app/features/admin/help/github-setup.html new file mode 100644 index 00000000..729d1e40 --- /dev/null +++ b/ahk-frontend/src/app/features/admin/help/github-setup.html @@ -0,0 +1,305 @@ +
+
+
+ Site administration / Help +

Setting up the GitHub App

+

+ Every course acts on GitHub through a GitHub App installed on that course's organization. + This page walks through registering and installing one, and shows where each value the + GitHub integration form asks for comes from. +

+
+
+ +
+
+
+

Why an App, and one per organization

+
+
+
+

+ Each course points at its own GitHub organization, administered by different people. A GitHub App is + owned by the organization rather than a person: its permissions are declared up front and visible to the + organization's owners, and it can be uninstalled at any time without touching any other course. +

+

+ The App both receives webhooks (pushes, pull requests, comments, workflow runs) and creates student + repositories from an assignment's template. One App serves both — if the organization already has an App + for github-monitor, extend that one rather than registering a second. +

+
+
+ +
+
+
+

1 · Register the App

+

Do this once per organization, as an organization owner.

+
+ @if (org(); as o) { + + Open on GitHub ↗ + + } +
+
+
    +
  1. + Go to the organization's Settings → Developer settings → GitHub Apps → New GitHub App. +
  2. +
  3. GitHub App name — something identifiable, e.g. AHK viaubc01.
  4. +
  5. Homepage URLhttps://ahk.aut.bme.hu.
  6. +
  7. + Webhook — tick Active, set the + Webhook URL to https://ahk.aut.bme.hu/api/integrations/github, + and generate a long random Webhook secret (you will paste this into the portal in + step 3, so keep it). +

    + The portal's webhook receiver is not ported yet. Until it is, point the webhook at + the course's existing github-monitor Function URL instead, and keep using + that. Everything else on this page already applies. +

    +
  8. +
  9. + Permissions — set exactly what the table below lists, and + nothing more. +
  10. +
  11. + Subscribe to events (webhook side only) — Pull request, + Pull request review, Issue comment, Push, Create, + Repository, Workflow run. +
  12. +
  13. Where can this GitHub App be installed?Only on this account.
  14. +
  15. + Create it. Then, on the App's page: +
      +
    • note the App ID;
    • +
    • + choose Generate a private key — GitHub downloads a .pem + file. +
    • +
    +
  16. +
+

+ The private key can only be downloaded once, at the moment you generate it. GitHub keeps + the public half and shows you the key only this one time — save the .pem before + leaving the page. If you lose it, generate a new one (the old one keeps working until you delete it). +

+
+
+ +
+
+
+

2 · Install it on the organization

+
+
+
+

On the App's page choose Install App and pick the organization.

+

+ Repository access must be “All repositories”. Repositories created for students do not + exist when the App is installed, so under Only select repositories they fall outside the + installation — the portal creates the repository and then gets a 404 from the + very next call. The health check warns about this before it happens. +

+
+
+ +
+
+
+

3 · Permissions

+

Set these under Repository permissions. Organization permissions are not needed.

+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PermissionLevelWhy
AdministrationRead & write + Creating a repository from a template, adding a student as a collaborator, managing invitations, + and setting a repository's Actions permissions all sit behind this one. + This is the grant to add if the App already exists for github-monitor. +
MetadataRead-onlyMandatory for every App. Also backs the check that a template repository exists.
ContentsRead-onlyReading the template repository. github-monitor needs Read & write here for its own work.
Pull requestsRead & writegithub-monitor only: comments, merges, assignees.
IssuesRead & writegithub-monitor only: issue comments carry the /ahk ok chatops.
ActionsRead-onlygithub-monitor only: counting workflow runs against the course threshold.
+
+

+ Administration: write is broad — it also permits changing repository settings and + deleting repositories. There is no narrower permission that covers creating repositories and adding + collaborators, so this is the floor, not a choice. +

+
+
+ +
+
+
+

4 · Where each value goes in the portal

+

Back in Courses → course → GitHub integration, fill these three fields.

+
+
+
+
+
GitHub App ID
+
The App ID from the App's page (a number, e.g. 123456).
+ +
App private key
+
+ Paste the entire contents of the .pem file, the + -----BEGIN line included. The bare base64 body that + github-monitor holds is also accepted, so a course being migrated can paste + what it already has. +
+ +
Webhook secret
+
The random string you generated for the App's webhook in step 1.
+
+

+ Stored credentials are never shown again. Leaving a field empty means + leave the stored value alone; use the field's Clear toggle to remove one. That + is what makes saving an untouched form safe. +

+
+
+ +
+
+
+

The access token

+

A separate personal access token — not part of the App above.

+
+ + Create a token ↗ + +
+
+

+ The Access token field on the integration form takes a GitHub personal access + token, created on your own GitHub account — it is independent of the course's GitHub App. Today + the portal uses it for one thing only: the health check calls + GET /user and GET /orgs/{org} with it to + confirm the portal can reach GitHub and see the course's organization. Leaving it blank simply leaves + that one check unconfigured; it does not affect the App. +

+

Create one under GitHub → Settings → Developer settings → Personal access tokens:

+
    +
  • + a classic token (ghp_…) with the + read:org and repo scopes, or +
  • +
  • + a fine-grained token (github_pat_…) scoped to the course's + organization with read access. +
  • +
+

+ Paste it into the Access token field. As with the App secrets, leaving it empty keeps + the stored value, and each save can Clear it. +

+
+
+ +
+
+
+

Not from GitHub: CI callback tokens

+
+
+
+

+ The CI callback tokens card next to GitHub integration is a separate + concern — it has nothing to do with the App above. Those tokens are generated + here in the portal, not on GitHub. The evaluator workflow uses one to sign its result + submissions back to the portal (an HMAC in the X-Ahk-Token header), so the + portal can trust that a set of grades really came from that course's CI. +

+

+ Do not confuse the webhook secret (a GitHub value, documented above) with a + CI callback token (issued by the portal). They protect traffic going in opposite + directions. +

+
+
+ +
+
+
+

When something's wrong

+
+
+
+

+ Site administration → Health runs the per-course checks and points at + whichever of the steps above failed. The most common failures: +

+
    +
  • + 401 from the token endpoint — wrong App ID, or the private key was revoked or pasted + incompletely. Generate a new key and store it again. +
  • +
  • + 404 on the installation — the App is registered but not installed on that + organization, or the course's organization name is wrong. +
  • +
  • + “administration: write” not granted — GitHub does not apply added permissions until an + owner approves them on the organization's installation page. Changing the App alone is not enough. +
  • +
  • + “limited to selected repositories” — change the installation's repository access to + All repositories (step 2). +
  • +
  • + Access token rejected — a 401 means the personal access + token is invalid, revoked or expired: issue a new one and save it. A 403 or + “cannot read the organization” means it is missing the read:org and + repo scopes, or has no access to that organization. +
  • +
+
+
+
diff --git a/ahk-frontend/src/app/features/admin/help/github-setup.scss b/ahk-frontend/src/app/features/admin/help/github-setup.scss new file mode 100644 index 00000000..87dedd4e --- /dev/null +++ b/ahk-frontend/src/app/features/admin/help/github-setup.scss @@ -0,0 +1,77 @@ +/* The global .notice is display:flex to seat an optional leading icon. Our callouts carry rich inline content + (bold, mono spans) and no icon, so flex would split each run into its own column — force normal block flow. */ +.notice { + display: block; +} + +/* Readable running text for the guide. Component-scoped, so it does not leak into other cards' bodies. */ +.prose { + font-size: 0.875rem; + line-height: 1.55; + + p { + margin: 0 0 0.75rem; + } + + ol, + ul { + margin: 0 0 0.75rem; + padding-left: 1.25rem; + + li { + margin-bottom: 0.4rem; + } + + ul { + margin: 0.4rem 0 0; + } + } + + > :last-child { + margin-bottom: 0; + } + + .notice { + margin: 0.5rem 0; + } +} + +/* Guidance under the permissions table and the CI-token aside. */ +.hint { + font-size: 0.8125rem; + color: var(--ink-2); + margin: 0.75rem 0 0; +} + +/* GitHub value → portal field mapping. Mirrors the .kv in the course editor so the two read alike. */ +.kv { + display: grid; + grid-template-columns: auto 1fr; + gap: 0.35rem 1rem; + margin: 0 0 1rem; + font-size: 0.8125rem; + + dt { + font-family: var(--font-ui); + font-size: 0.625rem; + letter-spacing: 0.1em; + text-transform: uppercase; + color: var(--ink-2); + padding-top: 0.15rem; + } + + dd { + margin: 0; + } +} + +@media (max-width: 40rem) { + .kv { + grid-template-columns: 1fr; + gap: 0.15rem; + + dd { + margin-bottom: 0.6rem; + } + } +} diff --git a/ahk-frontend/src/app/features/admin/help/github-setup.ts b/ahk-frontend/src/app/features/admin/help/github-setup.ts new file mode 100644 index 00000000..287896f8 --- /dev/null +++ b/ahk-frontend/src/app/features/admin/help/github-setup.ts @@ -0,0 +1,28 @@ +import { Component, inject } from '@angular/core'; +import { toSignal } from '@angular/core/rxjs-interop'; +import { ActivatedRoute, RouterLink } from '@angular/router'; +import { map } from 'rxjs'; + +/** + * A read-only guide to registering the per-course GitHub App and finding the values the GitHub integration + * form asks for. It is static prose — the authoritative copy lives in ahk-backend/docs/github-app.md and the + * two must be kept in step. + * + * When opened from a course's integration card the organization is passed as ?org=, which lets the page render + * a direct link into that organization's Developer settings. Without it the guide still stands on its own. + */ +@Component({ + selector: 'app-github-setup-help', + imports: [RouterLink], + templateUrl: './github-setup.html', + styleUrl: './github-setup.scss', +}) +export class GitHubSetupHelp { + private readonly route = inject(ActivatedRoute); + + /** The organization to deep-link into, when the page was opened from a specific course. */ + protected readonly org = toSignal( + this.route.queryParamMap.pipe(map((p) => p.get('org')?.trim() || null)), + { initialValue: null }, + ); +} diff --git a/ahk-frontend/src/app/features/admin/users/users.html b/ahk-frontend/src/app/features/admin/users/users.html index 2aea480e..23975d27 100644 --- a/ahk-frontend/src/app/features/admin/users/users.html +++ b/ahk-frontend/src/app/features/admin/users/users.html @@ -52,16 +52,23 @@

Add local account

- - At least 6 characters. Tell the person to change it after signing in. +
+ + +
+ + At least 6 characters, shown in the clear so you can copy it. Tell the person to change it after + signing in. +
diff --git a/ahk-frontend/src/app/features/admin/users/users.scss b/ahk-frontend/src/app/features/admin/users/users.scss index 7fe241e9..206261bb 100644 --- a/ahk-frontend/src/app/features/admin/users/users.scss +++ b/ahk-frontend/src/app/features/admin/users/users.scss @@ -83,3 +83,18 @@ h3 { font-size: 0.75rem; margin: 0; } + +.password-row { + display: flex; + align-items: stretch; + gap: 0.5rem; + + input { + flex: 1 1 auto; + } + + .btn { + flex: 0 0 auto; + white-space: nowrap; + } +} diff --git a/ahk-frontend/src/app/features/admin/users/users.ts b/ahk-frontend/src/app/features/admin/users/users.ts index a04ffbb8..540c252f 100644 --- a/ahk-frontend/src/app/features/admin/users/users.ts +++ b/ahk-frontend/src/app/features/admin/users/users.ts @@ -221,6 +221,50 @@ export class AdminUsers implements OnInit { }); } + /** + * Fill the password field with a fresh 16-character secret drawn from the CSPRNG. The character set spans + * upper/lower letters, digits and symbols; rejection sampling keeps the distribution uniform (a plain + * `% length` would bias toward the first characters). We seed one of each class up front so the result + * always satisfies a mixed-complexity policy, then shuffle so the class positions are not predictable. + */ + protected generatePassword(): void { + const classes = [ + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', + 'abcdefghijklmnopqrstuvwxyz', + '0123456789', + '!@#$%^&*()-_=+[]{};:,.?', + ]; + const all = classes.join(''); + const length = 16; + + // Uniform integer in [0, bound) via rejection sampling — a plain `% bound` would bias toward small values. + const randomInt = (bound: number): number => { + const max = Math.floor(256 / bound) * bound; + const buf = new Uint8Array(1); + let byte: number; + do { + crypto.getRandomValues(buf); + byte = buf[0]; + } while (byte >= max); + return byte % bound; + }; + + const pick = (set: string): string => set[randomInt(set.length)]; + + const chars = classes.map((set) => pick(set)); + while (chars.length < length) { + chars.push(pick(all)); + } + + // Fisher–Yates with CSPRNG-drawn indices so the guaranteed one-per-class characters are not stuck at the front. + for (let i = chars.length - 1; i > 0; i--) { + const j = randomInt(i + 1); + [chars[i], chars[j]] = [chars[j], chars[i]]; + } + + this.newPassword = chars.join(''); + } + protected cancelAdding(): void { this.adding.set(false); this.newUserName = ''; diff --git a/ahk-frontend/src/app/features/course/assignments/assignments.html b/ahk-frontend/src/app/features/course/assignments/assignments.html index d125303e..41e5d096 100644 --- a/ahk-frontend/src/app/features/course/assignments/assignments.html +++ b/ahk-frontend/src/app/features/course/assignments/assignments.html @@ -22,6 +22,12 @@

Assignments

@if (saved(); as s) {

{{ s }}

} + @if (templateWarning(); as w) { +

+ Saved, but the template repository has a problem — students will not be able to accept until it is fixed: + {{ w }} +

+ } @if (creating() || editingId() !== null) {
@@ -79,25 +85,29 @@

{{ editingId() === null ? 'Add assignment' : 'Edit assignment' }}

Optional. Shown under the assignment name on the accept screen.
- - @if (editingId() !== null) { -
- -
+ +
+ +
- @if (template(); as t) { - @if (t.problem) { -

{{ t.problem }}

- } @else { -

- The template is reachable and marked as a template repository. - @if (t.htmlUrl) { - Open it on GitHub - } -

- } + @if (template(); as t) { + @if (t.problem) { +

{{ t.problem }}

+ } @else { +

+ The template is reachable and marked as a template repository. + @if (t.htmlUrl) { + Open it on GitHub + } +

} }
diff --git a/ahk-frontend/src/app/features/course/assignments/assignments.ts b/ahk-frontend/src/app/features/course/assignments/assignments.ts index 4b34815e..40020b11 100644 --- a/ahk-frontend/src/app/features/course/assignments/assignments.ts +++ b/ahk-frontend/src/app/features/course/assignments/assignments.ts @@ -49,6 +49,8 @@ export class CourseAssignments implements OnInit { /** Advisory check of the template repository; costs a GitHub call, so it is only run on demand. */ protected readonly template = signal(null); protected readonly checkingTemplate = signal(false); + /** After a save, the template problem (if any) for the just-saved assignment, shown above the list. */ + protected readonly templateWarning = signal(null); // ---- Acceptance roster ---- protected readonly expandedId = signal(null); @@ -133,6 +135,9 @@ export class CourseAssignments implements OnInit { ); this.cancelEdit(); this.load(); + // Re-verify the template now that it is saved, so a tester who never opens the check still sees a + // problem before students hit it at accept time. Advisory: it never affects whether the save succeeded. + this.verifySavedTemplate(assignment.name ?? '', request.templateRepoName ?? ''); }, error: (err: unknown) => { this.savingForm.set(false); @@ -143,24 +148,43 @@ export class CourseAssignments implements OnInit { /** * Asks GitHub whether the template repository exists and is marked as a template. Advisory only — an - * assignment may legitimately be drafted before its template does. + * assignment may legitimately be drafted before its template does. Works in both create and edit mode + * because it checks the name currently in the field, not a stored assignment. */ protected checkTemplate(): void { - const id = this.editingId(); - if (id === null) { + const repo = this.templateRepoName.trim(); + if (!repo) { return; } this.checkingTemplate.set(true); - this.client.get(id, this.course, true).subscribe({ - next: (detail) => { - this.template.set(detail.template ?? null); + this.client.checkTemplate({ templateRepoName: repo }, this.course).subscribe({ + next: (result) => { + this.template.set(result); this.checkingTemplate.set(false); }, error: () => this.checkingTemplate.set(false), }); } + /** Runs the template check for a just-saved assignment and, if there is a problem, surfaces it above the list. */ + private verifySavedTemplate(assignmentName: string, templateRepoName: string): void { + this.templateWarning.set(null); + if (!templateRepoName) { + return; + } + + this.client.checkTemplate({ templateRepoName }, this.course).subscribe({ + next: (result) => { + if (result.problem) { + this.templateWarning.set(`"${assignmentName}": ${result.problem}`); + } + }, + // A failed advisory check must never look like a failed save; stay silent. + error: () => {}, + }); + } + // ---- Invite link ---- /** @@ -256,5 +280,6 @@ export class CourseAssignments implements OnInit { private clearMessages(): void { this.error.set(null); this.saved.set(null); + this.templateWarning.set(null); } } diff --git a/ahk-frontend/src/app/layout/shell/shell.html b/ahk-frontend/src/app/layout/shell/shell.html index 0a0e853f..57226ccc 100644 --- a/ahk-frontend/src/app/layout/shell/shell.html +++ b/ahk-frontend/src/app/layout/shell/shell.html @@ -45,6 +45,7 @@ Courses Users Health + GitHub setup } @else { {{ activeCourse()?.name || activeSlug() }} Submissions @@ -61,6 +62,7 @@ Courses Users Health + GitHub setup } } From 16929d83eb8cdbf21418b92b1dbfaf35592e98dd Mon Sep 17 00:00:00 2001 From: Bence Kovari Date: Sat, 8 Aug 2026 23:43:00 +0200 Subject: [PATCH 09/19] assignment repo prefix, local deployment script --- .claude/settings.json | 4 +- .gitignore | 4 + CLAUDE.md | 7 +- .../Ahk.Web.Data/Entities/Assignment.cs | 7 + ...05038_AssignmentRepoNamePrefix.Designer.cs | 1011 +++++++++++++++++ ...20260805005038_AssignmentRepoNamePrefix.cs | 28 + .../ApplicationDbContextModelSnapshot.cs | 3 + .../AssignmentInviteTests.cs | 17 +- .../Courses/AssignmentsController.cs | 2 + .../Courses/Dto/AssignmentDto.cs | 9 + .../Assignments/AssignmentInviteService.cs | 20 +- .../Assignments/AssignmentService.cs | 12 + ahk-frontend/src/app/api/api-client.ts | 2 + .../course/assignments/assignments.html | 85 +- .../course/assignments/assignments.scss | 32 + .../course/assignments/assignments.ts | 4 + deploy.local.json.example | 6 + scripts/deploy-local.cmd | 6 + scripts/deploy-local.sh | 187 +++ 19 files changed, 1395 insertions(+), 51 deletions(-) create mode 100644 ahk-backend/Ahk.Web.Data/Migrations/20260805005038_AssignmentRepoNamePrefix.Designer.cs create mode 100644 ahk-backend/Ahk.Web.Data/Migrations/20260805005038_AssignmentRepoNamePrefix.cs create mode 100644 deploy.local.json.example create mode 100644 scripts/deploy-local.cmd create mode 100644 scripts/deploy-local.sh diff --git a/.claude/settings.json b/.claude/settings.json index f96cc89f..a763c6cd 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -99,7 +99,9 @@ "Bash(node -e \"const {readFileSync}=require\\('fs'\\); const b=readFileSync\\('help-page.png'\\); console.log\\('png bytes:', b.length\\);\")", "Bash(node shot3.mjs)", "PowerShell(try { Get-NetTCPConnection -LocalPort 7443 -State Listen -ErrorAction Stop | Select-Object -ExpandProperty OwningProcess -Unique | ForEach-Object { Stop-Process -Id $_ -Force -ErrorAction SilentlyContinue } } catch {}; Write-Output \"backend stopped\")", - "Bash(node shot4.mjs)" + "Bash(node shot4.mjs)", + "Bash(wsl.exe bash *)", + "Bash(node shot5.mjs)" ], "additionalDirectories": [ "\\tmp", diff --git a/.gitignore b/.gitignore index 88dbff17..bf90ad17 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ .vs/ + +## Local deploy script (scripts/deploy-local.sh) — never commit secrets or build output +deploy.local.json +publish-local/ diff --git a/CLAUDE.md b/CLAUDE.md index 99df1134..465221d5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -64,7 +64,8 @@ Design decisions (rationale in the architecture plan and `ahk-backend/README.md` - **Admin API credential rule**: stored secrets are never returned (only `has*` flags plus a last-four hint). On update, each credential field means: `null` = leave alone, `""` = clear, anything else = replace. That is what makes saving an untouched form safe. - **Course health checks** (`Ahk.Web.Services/Health/`): each is an `ICourseHealthCheck` registered in DI and discovered by `CourseHealthService`, so adding one is a class plus a registration line — controller and UI unchanged. Three today: webhook settings (local), GitHub access token (real call to api.github.com, 10s timeout), CI callback token. Checks must not throw; return a `Failed` result instead, or one unreachable course takes the whole dashboard down. A course's status is the worst of its checks. - **Dev**: both run HTTPS. The Angular dev proxy (`proxy.conf.js`) forwards `/api/*` to the backend so calls are **same-origin — no CORS**, and `API_BASE_URL` is provided as `''` so generated clients issue relative requests. Press F5 with the **"Full stack (backend + frontend)"** compound in `.vscode/launch.json` to start both. -- **Domain model** (`Ahk.Web.Data/Entities`): `Course` 1:1 `CourseGitHubConfig` (per-course GitHub App creds + `WorkflowRunThreshold` — was per-deployment `AHK_*` — plus `GitHubAccessToken`, a PAT used for REST calls that need no installation token, today only the health check); `Student`/`Submission` replace the neptun/repo-name strings; `SubmissionEvent` (TPH: Repository/Branch/PullRequest/WorkflowRun) and `GradeRecord`+`GradeExercisePoint` are **append-only** — current state is projected, never updated. `CourseWebhookToken.Token` is globally unique because the CI callback carries no `{course}` segment. +- **Domain model** (`Ahk.Web.Data/Entities`): `Course` 1:1 `CourseGitHubConfig` (per-course GitHub App creds + `WorkflowRunThreshold` — was per-deployment `AHK_*` — plus `GitHubAccessToken`, a PAT used for REST calls that need no installation token, today only the health check); `Student`/`Submission` replace the neptun/repo-name strings; `SubmissionEvent` (TPH: Repository/Branch/PullRequest/WorkflowRun) and `GradeRecord`+`GradeExercisePoint` are **append-only** — current state is projected, never updated. `CourseWebhookToken.Token` is globally unique because the CI callback carries no `{course}` segment; its `Secret` is a plaintext column (HMAC needs the raw key) and the admin API **returns it** (list + detail) so the console can re-copy it later — a deliberate exception to the never-return rule, justified because any admin can mint an equivalent token anyway. +- **Assignments** (`Ahk.Web.Data/Entities/Assignment.cs`): student repos are named `{RepoNamePrefix}-{neptun}`, falling back to the template repo's bare name when `RepoNamePrefix` is blank (keeps pre-prefix assignments working) — logic in `AssignmentInviteService.BuildRepositoryName`. The template repo is validated **advisorily** (`AssignmentService.CheckTemplateAsync` → `POST api/{course}/assignments/check-template`): it reports existence + `is_template` as a warning and **never blocks saving** (an assignment may be drafted before its template exists). A bad template otherwise only fails at student-accept time as a 502. - ⚠️ **The course query filter matches nothing when no course is resolved.** `ICurrentCourseProvider` is set by whichever entry point resolved the course. Anything without HTTP course context — dev seeder, importer, services — must use `IgnoreQueryFilters()` and filter on `courseId` itself, or it silently reads **zero rows**. Service methods therefore always take an explicit `int courseId` and never read the provider. ## Build, test, run @@ -104,7 +105,7 @@ dotnet ef migrations add --project Ahk.Web.Data --startup-project Ahk.Web ``` Needs MSSQL (LocalDB by default; `ConnectionStrings:Default` in `appsettings.Development.json`). The dev seeder (Development env only) creates `admin`/`Admin123!` (site admin), `instructor`/`Instructor123!` (member of `viaubc01` only), courses `viaubc01`/`viaubb01` with GitHub config + CI token, and sample students/submissions/events/grades. The two courses are deliberately configured differently so the admin health dashboard shows a mix of states. -⚠️ **The seeder is create-if-missing.** Editing seeded values changes nothing on a dev database that already has those rows — delete the course (or the database) to see the new values. +⚠️ **The seeder is create-if-missing.** Editing seeded values changes nothing on a dev database that already has those rows — delete the course (or the database) to see the new values. It also calls `db.Database.MigrateAsync()` on startup, so running the backend in Development **auto-applies pending migrations** to the dev DB (prod still applies the `migrate.sql` artifact by hand). ```bash # one-time Cosmos-export import (throwaway tool; delete once every course is migrated) @@ -131,7 +132,7 @@ npm run generate-api # regenerate src/app/api from the backend's OpenAPI (back - **Auth cookies are named `ahk.auth` / `ahk.auth.external`, not the framework defaults** (`Program.ApplicationCookieName`). Browsers scope cookies by host and **ignore the port**, so on `localhost` every ASP.NET Identity app shares `.AspNetCore.Identity.Application`. A cookie from another project whose user id is a GUID reaches this int-keyed app and throws `"… is not a valid value for Int32"` inside `SecurityStampValidator` — a 500 on *every* request, including login. `OnValidatePrincipal` also wraps the stamp validator so an unreadable cookie signs the caller out instead of throwing. Do not revert either to the defaults. - **Windows PowerShell 5.1 cannot load .NET 10 assemblies** (`Add-Type` throws); to find a type's namespace, `grep -ao` the DLL instead. - **No Docker in this environment** — dev dependencies are built in-app (e.g. the mock OIDC provider), not containerized. -- **Verify UI changes by screenshotting the running app**, not by trusting the build. Chrome is at `/c/Program Files/Google/Chrome/Application/chrome.exe`. A plain `--headless=new --screenshot` fires before Angular hydrates and yields a near-empty page — add `--virtual-time-budget=4000`. For screens behind login, start Chrome with `--remote-debugging-port=9222` and drive the DevTools protocol from a Node script: Node 24 ships a built-in `WebSocket`, so this needs no npm dependency. Always pass `--ignore-certificate-errors` (self-signed dev cert). +- **Verify UI changes by screenshotting the running app**, not by trusting the build. Chrome is at `/c/Program Files/Google/Chrome/Application/chrome.exe`. A plain `--headless=new --screenshot` fires before Angular hydrates and yields a near-empty page — add `--virtual-time-budget=4000`. For screens behind login, start Chrome with `--remote-debugging-port=9222` and drive the DevTools protocol from a Node script: Node 24 ships a built-in `WebSocket`, so this needs no npm dependency. Always pass `--ignore-certificate-errors` (self-signed dev cert). When reading a value back from `Runtime.evaluate`, the RemoteObject is doubly nested at `msg.result.result.value` — reading `msg.result.value` silently yields `undefined` (the clicks still fire, so screenshots look fine while probes read blank). - **No image tooling** — no PIL, no ImageMagick. To read a PNG's pixels (sampling a brand colour, checking dimensions) decode it by hand with `zlib` + `struct`. EPS files are text-ish: `%%CMYKCustomColor` in the header carries the print colour spec. - **Prod hosting is same-origin**: the backend serves the Angular SPA — `UseDefaultFiles`/`UseStaticFiles` + `MapFallbackToFile("index.html")` in `Program.cs`, `ng build` output copied into `wwwroot`. Only dev uses the proxy. - **`web.config` is checked in with its SDK transform disabled** (`IsTransformWebConfigDisabled=true`): Mezga registers ANCM under the **V1** name `AspNetCoreModule`, so the SDK-generated V2 web.config fails to start the app there. Don't delete the file or re-enable the transform. diff --git a/ahk-backend/Ahk.Web.Data/Entities/Assignment.cs b/ahk-backend/Ahk.Web.Data/Entities/Assignment.cs index 075dbe8c..0856a38f 100644 --- a/ahk-backend/Ahk.Web.Data/Entities/Assignment.cs +++ b/ahk-backend/Ahk.Web.Data/Entities/Assignment.cs @@ -27,6 +27,13 @@ public class Assignment : ICourseScoped ///
public string TemplateRepoName { get; set; } = string.Empty; + /// + /// Prefix for the student repositories generated from this assignment: each clone is named + /// {RepoNamePrefix}-{neptun}. When blank, the template repository's own name is used instead (the + /// original behaviour), so assignments created before this field keep their naming unchanged. + /// + public string? RepoNamePrefix { get; set; } + /// /// Random, unguessable segment of the invite URL (/{course}/invite/{token}). A readable slug would /// let any signed-in user guess another course's assignment and provision themselves a repository, so the diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260805005038_AssignmentRepoNamePrefix.Designer.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260805005038_AssignmentRepoNamePrefix.Designer.cs new file mode 100644 index 00000000..9100f845 --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Migrations/20260805005038_AssignmentRepoNamePrefix.Designer.cs @@ -0,0 +1,1011 @@ +// +using System; +using Ahk.Web.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Ahk.Web.Data.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20260805005038_AssignmentRepoNamePrefix")] + partial class AssignmentRepoNamePrefix + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "10.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("Affiliation") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("GitHubUserId") + .HasColumnType("bigint"); + + b.Property("GitHubUsername") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NeptunCode") + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NeptunCode") + .IsUnique() + .HasFilter("[NeptunCode] IS NOT NULL"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Assignment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ArchivedAt") + .HasColumnType("datetimeoffset"); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("Description") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("InviteToken") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("RepoNamePrefix") + .HasColumnType("nvarchar(max)"); + + b.Property("TemplateRepoName") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.HasKey("Id"); + + b.HasIndex("InviteToken") + .IsUnique(); + + b.HasIndex("CourseId", "ArchivedAt"); + + b.ToTable("Assignments"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.AssignmentAcceptance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AcceptedAt") + .HasColumnType("datetimeoffset"); + + b.Property("AssignmentId") + .HasColumnType("int"); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("GitHubRepoName") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("GitHubUsername") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("InvitationId") + .HasColumnType("bigint"); + + b.Property("InvitationPending") + .HasColumnType("bit"); + + b.Property("InvitationSentAt") + .HasColumnType("datetimeoffset"); + + b.Property("RepoUrl") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.HasIndex("AssignmentId", "UserId") + .IsUnique(); + + b.HasIndex("CourseId", "GitHubRepoName"); + + b.ToTable("AssignmentAcceptances"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("GitHubOrganization") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("RepoNamePrefix") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("GitHubOrganization"); + + b.HasIndex("RepoNamePrefix"); + + b.HasIndex("Slug") + .IsUnique(); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseGitHubConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("bit"); + + b.Property("GitHubAccessToken") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("GitHubAppId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("GitHubAppPrivateKey") + .HasColumnType("nvarchar(max)"); + + b.Property("GitHubWebhookSecret") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("UpdatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("WorkflowRunThreshold") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CourseId") + .IsUnique(); + + b.ToTable("CourseGitHubConfigs"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("Role") + .HasColumnType("int"); + + b.HasKey("UserId", "CourseId"); + + b.HasIndex("CourseId"); + + b.ToTable("CourseMemberships"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseWebhookToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("Description") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("RevokedAt") + .HasColumnType("datetimeoffset"); + + b.Property("Secret") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("Token") + .IsUnique(); + + b.ToTable("CourseWebhookTokens"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeExercisePoint", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("GradeRecordId") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("Point") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.HasIndex("GradeRecordId"); + + b.ToTable("GradeExercisePoints"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Actor") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Confirmed") + .HasColumnType("bit"); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("Date") + .HasColumnType("datetimeoffset"); + + b.Property("Neptun") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("Origin") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("PrNumber") + .HasColumnType("int"); + + b.Property("PrUrl") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("StudentId") + .HasColumnType("int"); + + b.Property("SubmissionId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("StudentId"); + + b.HasIndex("SubmissionId"); + + b.HasIndex("CourseId", "Confirmed", "Date"); + + b.HasIndex("CourseId", "SubmissionId", "PrNumber", "Date"); + + b.ToTable("GradeRecords"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("GitHubUsername") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Neptun") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.HasKey("Id"); + + b.HasIndex("CourseId", "Neptun") + .IsUnique(); + + b.ToTable("Students"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetimeoffset"); + + b.Property("GitHubRepoId") + .HasColumnType("bigint"); + + b.Property("GitHubRepoName") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("LastEventAt") + .HasColumnType("datetimeoffset"); + + b.Property("StudentId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("StudentId"); + + b.HasIndex("CourseId", "GitHubRepoName") + .IsUnique(); + + b.HasIndex("CourseId", "StudentId"); + + b.ToTable("Submissions"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.SubmissionEvent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CourseId") + .HasColumnType("int"); + + b.Property("EventType") + .IsRequired() + .HasMaxLength(34) + .HasColumnType("nvarchar(34)"); + + b.Property("GitHubDeliveryId") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("SubmissionId") + .HasColumnType("int"); + + b.Property("Timestamp") + .HasColumnType("datetimeoffset"); + + b.HasKey("Id"); + + b.HasIndex("GitHubDeliveryId") + .IsUnique() + .HasFilter("[GitHubDeliveryId] IS NOT NULL"); + + b.HasIndex("SubmissionId"); + + b.HasIndex("CourseId", "SubmissionId", "Timestamp"); + + b.ToTable("SubmissionEvents"); + + b.HasDiscriminator("EventType").HasValue("SubmissionEvent"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.BranchCreatedEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.Property("Branch") + .IsRequired() + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.HasDiscriminator().HasValue("BranchCreatedEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.PullRequestEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.Property("Action") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.PrimitiveCollection("Assignees") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("HtmlUrl") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("Neptun") + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("Number") + .HasColumnType("int"); + + b.HasDiscriminator().HasValue("PullRequestEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.RepositoryCreatedEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.HasDiscriminator().HasValue("RepositoryCreatedEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.WorkflowRunEvent", b => + { + b.HasBaseType("Ahk.Web.Data.Entities.SubmissionEvent"); + + b.Property("Conclusion") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasDiscriminator().HasValue("WorkflowRunEvent"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Assignment", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.AssignmentAcceptance", b => + { + b.HasOne("Ahk.Web.Data.Entities.Assignment", "Assignment") + .WithMany("Acceptances") + .HasForeignKey("AssignmentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Assignment"); + + b.Navigation("Course"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseGitHubConfig", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithOne("GitHubConfig") + .HasForeignKey("Ahk.Web.Data.Entities.CourseGitHubConfig", "CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseMembership", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany("Memberships") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", "User") + .WithMany("CourseMemberships") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.CourseWebhookToken", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeExercisePoint", b => + { + b.HasOne("Ahk.Web.Data.Entities.GradeRecord", "GradeRecord") + .WithMany("Points") + .HasForeignKey("GradeRecordId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GradeRecord"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Student", "Student") + .WithMany() + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("Ahk.Web.Data.Entities.Submission", "Submission") + .WithMany("Grades") + .HasForeignKey("SubmissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + + b.Navigation("Student"); + + b.Navigation("Submission"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Student", "Student") + .WithMany("Submissions") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("Course"); + + b.Navigation("Student"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.SubmissionEvent", b => + { + b.HasOne("Ahk.Web.Data.Entities.Course", "Course") + .WithMany() + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.Submission", "Submission") + .WithMany("Events") + .HasForeignKey("SubmissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Course"); + + b.Navigation("Submission"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ahk.Web.Data.Entities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.ApplicationUser", b => + { + b.Navigation("CourseMemberships"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Assignment", b => + { + b.Navigation("Acceptances"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Course", b => + { + b.Navigation("GitHubConfig"); + + b.Navigation("Memberships"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.GradeRecord", b => + { + b.Navigation("Points"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Student", b => + { + b.Navigation("Submissions"); + }); + + modelBuilder.Entity("Ahk.Web.Data.Entities.Submission", b => + { + b.Navigation("Events"); + + b.Navigation("Grades"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/20260805005038_AssignmentRepoNamePrefix.cs b/ahk-backend/Ahk.Web.Data/Migrations/20260805005038_AssignmentRepoNamePrefix.cs new file mode 100644 index 00000000..7a7c77dd --- /dev/null +++ b/ahk-backend/Ahk.Web.Data/Migrations/20260805005038_AssignmentRepoNamePrefix.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ahk.Web.Data.Migrations +{ + /// + public partial class AssignmentRepoNamePrefix : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "RepoNamePrefix", + table: "Assignments", + type: "nvarchar(max)", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "RepoNamePrefix", + table: "Assignments"); + } + } +} diff --git a/ahk-backend/Ahk.Web.Data/Migrations/ApplicationDbContextModelSnapshot.cs b/ahk-backend/Ahk.Web.Data/Migrations/ApplicationDbContextModelSnapshot.cs index e17d116b..9c7c2dca 100644 --- a/ahk-backend/Ahk.Web.Data/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/ahk-backend/Ahk.Web.Data/Migrations/ApplicationDbContextModelSnapshot.cs @@ -174,6 +174,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(256) .HasColumnType("nvarchar(256)"); + b.Property("RepoNamePrefix") + .HasColumnType("nvarchar(max)"); + b.Property("TemplateRepoName") .IsRequired() .HasMaxLength(400) diff --git a/ahk-backend/Ahk.Web.Server.Tests/AssignmentInviteTests.cs b/ahk-backend/Ahk.Web.Server.Tests/AssignmentInviteTests.cs index 0753f45d..20ffff10 100644 --- a/ahk-backend/Ahk.Web.Server.Tests/AssignmentInviteTests.cs +++ b/ahk-backend/Ahk.Web.Server.Tests/AssignmentInviteTests.cs @@ -292,9 +292,16 @@ public async Task ACourseWithoutAnOrganization_ReportsItIsNotConfigured() } [Theory] - [InlineData("ahk-org/viaubc01-hw1", "ABC123", "viaubc01-hw1-abc123")] - [InlineData("org/hw", "xyz789", "hw-xyz789")] - [InlineData("no-owner", "ABC123", "no-owner-abc123")] - public void RepositoryName_IsTheTemplateNamePlusNeptun_Lowercased(string template, string neptun, string expected) => - Assert.Equal(expected, AssignmentInviteService.BuildRepositoryName(template, neptun)); + // No prefix set → falls back to the template repository's own name (the original behaviour). + [InlineData("ahk-org/viaubc01-hw1", null, "ABC123", "viaubc01-hw1-abc123")] + [InlineData("org/hw", null, "xyz789", "hw-xyz789")] + [InlineData("no-owner", null, "ABC123", "no-owner-abc123")] + // Prefix set → it is used instead of the template name, lowercased like every repository name. + [InlineData("ahk-org/viaubc01-hw1", "custom-prefix", "ABC123", "custom-prefix-abc123")] + [InlineData("ahk-org/viaubc01-hw1", "Custom", "xyz789", "custom-xyz789")] + public void RepositoryName_UsesPrefixOrFallsBackToTemplateName_Lowercased(string template, string? prefix, string neptun, string expected) + { + var assignment = new Assignment { TemplateRepoName = template, RepoNamePrefix = prefix }; + Assert.Equal(expected, AssignmentInviteService.BuildRepositoryName(assignment, neptun)); + } } diff --git a/ahk-backend/Ahk.Web.Server/Courses/AssignmentsController.cs b/ahk-backend/Ahk.Web.Server/Courses/AssignmentsController.cs index 56ff38f7..79931c82 100644 --- a/ahk-backend/Ahk.Web.Server/Courses/AssignmentsController.cs +++ b/ahk-backend/Ahk.Web.Server/Courses/AssignmentsController.cs @@ -206,6 +206,7 @@ private async Task> SetArchivedAsync(int id, bool ar Name = request.Name, Description = request.Description, TemplateRepoName = request.TemplateRepoName, + RepoNamePrefix = request.RepoNamePrefix, }; private AssignmentDto ToDto(Assignment assignment, Course course, int acceptanceCount) => new() @@ -214,6 +215,7 @@ private async Task> SetArchivedAsync(int id, bool ar Name = assignment.Name, Description = assignment.Description, TemplateRepoName = assignment.TemplateRepoName, + RepoNamePrefix = assignment.RepoNamePrefix, InvitePath = $"/{course.Slug}/invite/{assignment.InviteToken}", IsArchived = assignment.ArchivedAt is not null, ArchivedAt = assignment.ArchivedAt, diff --git a/ahk-backend/Ahk.Web.Server/Courses/Dto/AssignmentDto.cs b/ahk-backend/Ahk.Web.Server/Courses/Dto/AssignmentDto.cs index 4a840778..dedaf107 100644 --- a/ahk-backend/Ahk.Web.Server/Courses/Dto/AssignmentDto.cs +++ b/ahk-backend/Ahk.Web.Server/Courses/Dto/AssignmentDto.cs @@ -14,6 +14,9 @@ public sealed class AssignmentDto /// Full "owner/name" of the template repository students are given a copy of. public string TemplateRepoName { get; set; } = string.Empty; + /// Prefix for generated student repositories ({prefix}-{neptun}); null falls back to the template name. + public string? RepoNamePrefix { get; set; } + /// /// The invite link as a site-relative path (/{course}/invite/{token}). Deliberately not an absolute /// URL: the API would have to build one from the Host header, and the Angular dev proxy rewrites that to @@ -75,6 +78,12 @@ public sealed class SaveAssignmentRequest /// "owner/name", or a bare repository name taken to be in the course's organization. public string TemplateRepoName { get; set; } = string.Empty; + + /// + /// Prefix for generated student repositories ({prefix}-{neptun}). Blank/omitted falls back to the + /// template repository's name. + /// + public string? RepoNamePrefix { get; set; } } /// diff --git a/ahk-backend/Ahk.Web.Services/Assignments/AssignmentInviteService.cs b/ahk-backend/Ahk.Web.Services/Assignments/AssignmentInviteService.cs index e75a0a00..fa9e687c 100644 --- a/ahk-backend/Ahk.Web.Services/Assignments/AssignmentInviteService.cs +++ b/ahk-backend/Ahk.Web.Services/Assignments/AssignmentInviteService.cs @@ -158,7 +158,7 @@ public async Task AcceptAsync(int courseId, string inviteToken, App } var organization = course.GitHubOrganization!; - var repositoryName = BuildRepositoryName(assignment.TemplateRepoName, student.Neptun); + var repositoryName = BuildRepositoryName(assignment, student.Neptun); var fullName = Normalize.RepoName($"{organization}/{repositoryName}"); var existing = await gitHub.GetRepositoryAsync(organization, repositoryName, token.Token, cancellationToken); @@ -229,13 +229,19 @@ public async Task AcceptAsync(int courseId, string inviteToken, App } /// - /// The student's repository name: the template repository's own name with their Neptun code appended, the - /// convention the courses already use. Lowercased like every repository name in the model. + /// The student's repository name: the assignment's with their Neptun + /// code appended. When no prefix is set the template repository's own name is used instead — the original + /// convention, kept for assignments predating the prefix. Lowercased like every repository name in the model. /// - internal static string BuildRepositoryName(string templateRepoName, string neptun) + internal static string BuildRepositoryName(Assignment assignment, string neptun) { - var (_, name) = IAssignmentService.SplitRepoName(templateRepoName); - return Normalize.RepoName($"{name}-{neptun}"); + ArgumentNullException.ThrowIfNull(assignment); + + var prefix = assignment.RepoNamePrefix; + if (string.IsNullOrWhiteSpace(prefix)) + (_, prefix) = IAssignmentService.SplitRepoName(assignment.TemplateRepoName); + + return Normalize.RepoName($"{prefix}-{neptun}"); } private InviteState Describe(Course course, Assignment assignment, ApplicationUser user, AssignmentAcceptance? acceptance) @@ -276,7 +282,7 @@ private InviteState Describe(Course course, Assignment assignment, ApplicationUs return state; } - state.RepositoryName = BuildRepositoryName(assignment.TemplateRepoName, Normalize.Neptun(user.NeptunCode)); + state.RepositoryName = BuildRepositoryName(assignment, Normalize.Neptun(user.NeptunCode)); if (string.IsNullOrWhiteSpace(user.GitHubUsername)) { diff --git a/ahk-backend/Ahk.Web.Services/Assignments/AssignmentService.cs b/ahk-backend/Ahk.Web.Services/Assignments/AssignmentService.cs index a1966a7f..6c1f81e8 100644 --- a/ahk-backend/Ahk.Web.Services/Assignments/AssignmentService.cs +++ b/ahk-backend/Ahk.Web.Services/Assignments/AssignmentService.cs @@ -14,6 +14,9 @@ public sealed class AssignmentInput /// Either "owner/name" or a bare repository name, which is taken to be in the course's organization. public string TemplateRepoName { get; set; } = string.Empty; + + /// Prefix for generated student repositories ({prefix}-{neptun}); blank falls back to the template name. + public string? RepoNamePrefix { get; set; } } /// @@ -106,6 +109,7 @@ public async Task CreateAsync(int courseId, AssignmentInput input, C Name = input.Name.Trim(), Description = Trimmed(input.Description), TemplateRepoName = await QualifyRepoNameAsync(courseId, input.TemplateRepoName, cancellationToken), + RepoNamePrefix = NormalizedPrefix(input.RepoNamePrefix), InviteToken = TokenGenerator.UrlSafe(18), }; @@ -125,6 +129,7 @@ public async Task CreateAsync(int courseId, AssignmentInput input, C assignment.Name = input.Name.Trim(); assignment.Description = Trimmed(input.Description); assignment.TemplateRepoName = await QualifyRepoNameAsync(courseId, input.TemplateRepoName, cancellationToken); + assignment.RepoNamePrefix = NormalizedPrefix(input.RepoNamePrefix); await db.SaveChangesAsync(cancellationToken); return assignment; @@ -249,4 +254,11 @@ private async Task QualifyRepoNameAsync(int courseId, string templateRep } private static string? Trimmed(string? value) => string.IsNullOrWhiteSpace(value) ? null : value.Trim(); + + /// + /// Stores the repo-name prefix normalized like every other repository name (lowercased, trimmed), or null + /// when blank so falls back to the template name. + /// + private static string? NormalizedPrefix(string? value) => + string.IsNullOrWhiteSpace(value) ? null : Normalize.RepoName(value); } diff --git a/ahk-frontend/src/app/api/api-client.ts b/ahk-frontend/src/app/api/api-client.ts index 1986a106..9693c196 100644 --- a/ahk-frontend/src/app/api/api-client.ts +++ b/ahk-frontend/src/app/api/api-client.ts @@ -3148,6 +3148,7 @@ export interface AssignmentDto { name?: string; description?: string | undefined; templateRepoName?: string; + repoNamePrefix?: string | undefined; invitePath?: string; isArchived?: boolean; archivedAt?: Date | undefined; @@ -3175,6 +3176,7 @@ export interface SaveAssignmentRequest { name?: string; description?: string | undefined; templateRepoName?: string; + repoNamePrefix?: string | undefined; } export interface AssignmentAcceptanceDto { diff --git a/ahk-frontend/src/app/features/course/assignments/assignments.html b/ahk-frontend/src/app/features/course/assignments/assignments.html index 41e5d096..2c3b9b8b 100644 --- a/ahk-frontend/src/app/features/course/assignments/assignments.html +++ b/ahk-frontend/src/app/features/course/assignments/assignments.html @@ -58,46 +58,33 @@

{{ editingId() === null ? 'Add assignment' : 'Edit assignment' }}

- + +
+ + +
- A bare name is taken to be in this course's organization. Student repositories are named - <this>-<neptun>. + A bare name is taken to be in this course's organization, and must be marked as a template on + GitHub.
-
- - - Optional. Shown under the assignment name on the accept screen. -
- - -
- -
- @if (template(); as t) { @if (t.problem) {

{{ t.problem }}

@@ -110,6 +97,34 @@

{{ editingId() === null ? 'Add assignment' : 'Edit assignment' }}

} } + +
+
+ + + Optional. Shown under the assignment name on the accept screen. +
+
+ + + + Cloned student repositories are named <prefix>-<neptun>. + Leave blank to use the template repository's name. + +
+
diff --git a/ahk-frontend/src/app/features/course/assignments/assignments.scss b/ahk-frontend/src/app/features/course/assignments/assignments.scss index 293f74c4..d5af30ec 100644 --- a/ahk-frontend/src/app/features/course/assignments/assignments.scss +++ b/ahk-frontend/src/app/features/course/assignments/assignments.scss @@ -62,6 +62,38 @@ h2 { font-size: 0.75rem; } +/* The template field with its Validate button attached, so the action reads as part of the field. */ +.input-with-action { + display: flex; + gap: 0.5rem; + align-items: stretch; + + input { + flex: 1 1 auto; + min-width: 0; + } + + .btn { + flex: none; + justify-content: center; + } +} + +/* A crimson-outlined button — clearly a control, not the transparent "quiet" it replaced, but subordinate to + the solid crimson Save so the two never compete. */ +.btn.accent { + border-color: var(--accent); + background: var(--surface); + color: var(--accent); + font-weight: 600; + + &:hover:not(:disabled) { + background: var(--accent-wash); + border-color: var(--accent-ink); + color: var(--accent-ink); + } +} + /* Prose-weight toggle for the acceptance list — a button here would compete with the card's real actions. */ .linkish { border: 0; diff --git a/ahk-frontend/src/app/features/course/assignments/assignments.ts b/ahk-frontend/src/app/features/course/assignments/assignments.ts index 40020b11..d06498b5 100644 --- a/ahk-frontend/src/app/features/course/assignments/assignments.ts +++ b/ahk-frontend/src/app/features/course/assignments/assignments.ts @@ -45,6 +45,7 @@ export class CourseAssignments implements OnInit { protected name = ''; protected description = ''; protected templateRepoName = ''; + protected repoNamePrefix = ''; /** Advisory check of the template repository; costs a GitHub call, so it is only run on demand. */ protected readonly template = signal(null); @@ -94,6 +95,7 @@ export class CourseAssignments implements OnInit { this.name = ''; this.description = ''; this.templateRepoName = ''; + this.repoNamePrefix = ''; } protected startEdit(assignment: AssignmentDto): void { @@ -104,6 +106,7 @@ export class CourseAssignments implements OnInit { this.name = assignment.name ?? ''; this.description = assignment.description ?? ''; this.templateRepoName = assignment.templateRepoName ?? ''; + this.repoNamePrefix = assignment.repoNamePrefix ?? ''; } protected cancelEdit(): void { @@ -120,6 +123,7 @@ export class CourseAssignments implements OnInit { name: this.name.trim(), description: this.description.trim() || undefined, templateRepoName: this.templateRepoName.trim(), + repoNamePrefix: this.repoNamePrefix.trim() || undefined, }; const id = this.editingId(); diff --git a/deploy.local.json.example b/deploy.local.json.example new file mode 100644 index 00000000..aa90182f --- /dev/null +++ b/deploy.local.json.example @@ -0,0 +1,6 @@ +{ + "_comment": "Copy this file to deploy.local.json (gitignored) and fill in real values. Never commit deploy.local.json.", + "deploymentPath": "", + "databaseConnectionString": "", + "oidcClientSecret": "" +} diff --git a/scripts/deploy-local.cmd b/scripts/deploy-local.cmd new file mode 100644 index 00000000..10ad6e6b --- /dev/null +++ b/scripts/deploy-local.cmd @@ -0,0 +1,6 @@ +@echo off +rem Convenience launcher for deploy-local.sh from a Windows terminal (or double-click), regardless of +rem the current working directory. Any arguments (e.g. --force-full) are passed through. +pushd "%~dp0\.." +wsl bash scripts/deploy-local.sh %* +popd diff --git a/scripts/deploy-local.sh b/scripts/deploy-local.sh new file mode 100644 index 00000000..21abfd3a --- /dev/null +++ b/scripts/deploy-local.sh @@ -0,0 +1,187 @@ +#!/usr/bin/env bash +# Local (in-network) deploy to Mezga, run from WSL. Alternative to .github/workflows/ahk-web-deploy.yaml +# for when you're already inside the BME network and don't want to pay the VPN round-trip. +# +# Usage (from a WSL shell, or via scripts\deploy-local.cmd on Windows): +# wsl bash scripts/deploy-local.sh [--force-full] +# +# --force-full ignores the deployment manifest stored on the share and re-copies everything. Use this +# after any manual/out-of-band change on the server, since the manifest only reflects "what a deploy +# script last wrote", not "what is actually on disk right now". +# +# The manifest this script reads/writes (.deploy-manifest.sha256 at the share root) is byte-compatible +# with the one ahk-web-deploy.yaml produces: same sha256sum invocation, same relative-path convention. +# Either deploy path can pick up where the other left off. +set -euo pipefail + +# ---- Config ---- +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +BACKEND_PROJECT="ahk-backend/Ahk.Web.Server/Ahk.Web.Server.csproj" +FRONTEND_DIR="ahk-frontend" +OFFLINE_PAGE="ahk-backend/Ahk.Web.Server/app_offline.htm" +PUBLISH_DIR="publish-local" +MOUNT_POINT="/mnt/ahk-deploy-local" +MANIFEST_NAME=".deploy-manifest.sha256" +SECRETS_FILE="deploy.local.json" + +FORCE_FULL=false +if [ "${1:-}" = "--force-full" ]; then + FORCE_FULL=true +fi + +cd "$REPO_ROOT" + +# ---- Preflight ---- +missing=() +command -v dotnet.exe >/dev/null 2>&1 || missing+=("dotnet.exe (the .NET SDK, reached via Windows-PATH interop)") +command -v npm >/dev/null 2>&1 || missing+=("npm (Node, reached via Windows-PATH interop)") +command -v jq >/dev/null 2>&1 || missing+=("jq (install with: sudo apt-get install -y jq)") +command -v rsync >/dev/null 2>&1 || missing+=("rsync") +command -v curl >/dev/null 2>&1 || missing+=("curl") + +if [ "${#missing[@]}" -gt 0 ]; then + echo "Missing required tool(s):" + for m in "${missing[@]}"; do echo " - $m"; done + exit 1 +fi + +if [ ! -f "$SECRETS_FILE" ]; then + echo "Missing $SECRETS_FILE. Copy deploy.local.json.example to $SECRETS_FILE and fill in your values." + exit 1 +fi + +DEPLOYMENT_PATH=$(jq -r '.deploymentPath' "$SECRETS_FILE") +DATABASE_CONNECTIONSTRING=$(jq -r '.databaseConnectionString' "$SECRETS_FILE") +OIDC_CLIENTSECRET=$(jq -r '.oidcClientSecret' "$SECRETS_FILE") + +if [ -z "$DEPLOYMENT_PATH" ] || [ "$DEPLOYMENT_PATH" = "null" ]; then + echo "deploy.local.json is missing deploymentPath." + exit 1 +fi + +# ---- Git state visibility (informational only — a local deploy of WIP is a legitimate use case) ---- +echo "Deploying branch $(git rev-parse --abbrev-ref HEAD), commit $(git rev-parse --short HEAD)" +if [ -n "$(git status --porcelain)" ]; then + echo "NOTE: working tree has uncommitted changes — deploying them along with everything else." +fi + +# ---- Build ---- +echo "== Publishing backend (self-contained win-x64 via Mezga profile) ==" +rm -rf "$PUBLISH_DIR" +dotnet.exe publish "$BACKEND_PROJECT" -p:PublishProfile=Mezga -o "$PUBLISH_DIR" + +echo "== Building frontend (production) ==" +(cd "$FRONTEND_DIR" && npm ci && npx ng build --configuration production) + +echo "== Copying SPA into backend wwwroot ==" +mkdir -p "$PUBLISH_DIR/wwwroot" +cp -r "$FRONTEND_DIR/dist/ahk-frontend/browser/." "$PUBLISH_DIR/wwwroot/" + +# ---- Inject production config (never committed) ---- +echo "== Injecting connection string and OIDC client secret ==" +jq --arg cs "$DATABASE_CONNECTIONSTRING" --arg secret "$OIDC_CLIENTSECRET" \ + '.ConnectionStrings.Default = $cs | .Authentication.Oidc.ClientSecret = $secret' \ + "$PUBLISH_DIR/appsettings.json" > "$PUBLISH_DIR/appsettings.json.tmp" +mv "$PUBLISH_DIR/appsettings.json.tmp" "$PUBLISH_DIR/appsettings.json" + +# Last content-mutating step before the diff — identical invocation to the GitHub workflow, so the +# manifest either produces is byte-for-byte comparable. +echo "== Computing local deployment manifest ==" +(cd "$PUBLISH_DIR" && find . -type f -printf '%P\0' | sort -z | xargs -0 sha256sum) > new.manifest + +# ---- Mount the share, using the current Windows session's own access ---- +# drvfs proxies through the Windows kernel's SMB redirector, so whatever credentials Windows already +# has cached for this UNC path (from Explorer or a prior `net use`) are reused automatically — no +# separate Linux-side username/password, unlike the GitHub runner's mount -t cifs. +sudo mkdir -p "$MOUNT_POINT" +if ! mountpoint -q "$MOUNT_POINT"; then + echo "== Mounting $DEPLOYMENT_PATH ==" + if ! sudo mount -t drvfs "$DEPLOYMENT_PATH" "$MOUNT_POINT" -o "uid=$(id -u),gid=$(id -g)"; then + echo "::error::Could not mount $DEPLOYMENT_PATH." + echo "Windows needs to already have access to this share. From Windows, either:" + echo " - browse to $DEPLOYMENT_PATH in Explorer once and accept 'remember my credentials', or" + echo " - run: net use $DEPLOYMENT_PATH" + echo "then re-run this script." + exit 1 + fi +fi + +cleanup() { + sudo umount "$MOUNT_POINT" >/dev/null 2>&1 || true +} +trap cleanup EXIT + +# ---- Fetch previous deployment manifest ---- +if [ "$FORCE_FULL" = "true" ]; then + echo "--force-full requested — treating the stored manifest as empty (full re-copy)." + : > old.manifest +elif [ -f "$MOUNT_POINT/$MANIFEST_NAME" ]; then + cp "$MOUNT_POINT/$MANIFEST_NAME" old.manifest +else + echo "No manifest found on the share yet — treating this as a first-time full deploy." + : > old.manifest +fi + +# ---- Diff manifests (pure local text processing — no network cost) ---- +sort old.manifest -o old.sorted +sort new.manifest -o new.sorted + +# Changed or added: whole lines (hash+path) present in the new build but not the old one. +comm -13 old.sorted new.sorted | cut -c 67- > changed.list + +# Removed: paths that existed before and are entirely absent from the new build — correctly prunes +# Angular's abandoned content-hashed chunk files, unlike a size comparison. +cut -c 67- old.manifest | sort -u > old.paths +cut -c 67- new.manifest | sort -u > new.paths +comm -23 old.paths new.paths > removed.list + +changed=$(wc -l < changed.list) +removed=$(wc -l < removed.list) +echo "Changed/added: $changed, removed: $removed" + +if [ "$changed" -eq 0 ] && [ "$removed" -eq 0 ]; then + echo "Nothing changed — skipping the deploy." +else + echo "== Stopping site (app_offline.htm) ==" + cp "$OFFLINE_PAGE" "$MOUNT_POINT/app_offline.htm" + sleep 5 + + if [ -s changed.list ]; then + echo "== Copying changed files ==" + ok=false + for i in $(seq 1 10); do + if rsync -R --files-from=changed.list --ignore-times --whole-file --inplace \ + --no-perms --no-owner --no-group --no-times "$PUBLISH_DIR/" "$MOUNT_POINT/"; then + ok=true + break + fi + echo "rsync attempt $i failed (likely a locked file); retrying..." + sleep 2 + done + if [ "$ok" != "true" ]; then + echo "::error::Copying changed files failed after retries" + exit 1 + fi + fi + + if [ -s removed.list ]; then + echo "== Removing stale files ==" + while IFS= read -r path; do + rm -f "$MOUNT_POINT/$path" + done < removed.list + fi + + echo "== Waking site (removing app_offline.htm) ==" + rm -f "$MOUNT_POINT/app_offline.htm" + + echo "== Warming up and verifying ==" + curl --fail --show-error --retry 5 --retry-delay 3 https://ahk.aut.bme.hu/ + + # Last content-mutating step, only reached after everything above succeeded — a failed run leaves the + # old manifest in place, so the next run still sees these files as "changed" and retries them. + echo "== Publishing new deployment manifest ==" + cp new.manifest "$MOUNT_POINT/$MANIFEST_NAME" +fi + +echo "Done." From 9d83616bb2ab7f69a28f82bc742a9a2420bd0fe6 Mon Sep 17 00:00:00 2001 From: Bence Kovari Date: Sun, 9 Aug 2026 01:33:50 +0200 Subject: [PATCH 10/19] refactor(portal): move the GitHub API surface onto Octokit Adds Octokit to Ahk.Web.Services and introduces ICourseGitHubClientFactory as the single place the portal builds an authenticated GitHub client, ahead of porting github-monitor's handlers (which are written against Octokit's payload types and API surface). GitHubRepositoryService is rewritten on top of it. The interface and its four record projections are deliberately unchanged: they keep Octokit's models out of the domain, and they are what lets AssignmentInviteTests mock the service strictly - that suite is the regression net for this rewrite and still passes untouched. The named "github" HttpClient stays, but only for CourseGitHubAppTokenProvider's App-JWT bootstrap and the health checks. Converting the token provider would change the shape of the permissions dictionary GitHubAppInstallationHealthCheck reads, for no gain. Two Octokit 14 details worth recording: NewRepositoryFromTemplate has no IncludeAllBranches property (GitHub defaults it to false, which is what we want), and Repository.IsTemplate / RepositoryInvitation.Expired are non-nullable bool. Co-Authored-By: Claude Opus 5 --- .../Ahk.Web.Services/Ahk.Web.Services.csproj | 1 + .../GitHub/CourseGitHubClientFactory.cs | 65 ++++ .../GitHub/GitHubRepositoryService.cs | 309 ++++++++---------- .../ServiceCollectionExtensions.cs | 10 +- 4 files changed, 213 insertions(+), 172 deletions(-) create mode 100644 ahk-backend/Ahk.Web.Services/GitHub/CourseGitHubClientFactory.cs diff --git a/ahk-backend/Ahk.Web.Services/Ahk.Web.Services.csproj b/ahk-backend/Ahk.Web.Services/Ahk.Web.Services.csproj index 2974869a..65a49064 100644 --- a/ahk-backend/Ahk.Web.Services/Ahk.Web.Services.csproj +++ b/ahk-backend/Ahk.Web.Services/Ahk.Web.Services.csproj @@ -14,6 +14,7 @@ + diff --git a/ahk-backend/Ahk.Web.Services/GitHub/CourseGitHubClientFactory.cs b/ahk-backend/Ahk.Web.Services/GitHub/CourseGitHubClientFactory.cs new file mode 100644 index 00000000..40d262c7 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHub/CourseGitHubClientFactory.cs @@ -0,0 +1,65 @@ +using Octokit; +using Octokit.Internal; + +namespace Ahk.Web.Services.GitHub; + +public interface ICourseGitHubClientFactory +{ + /// + /// An Octokit client authenticated as the course's GitHub App installation, or null when the course has no + /// working App credentials. Null rather than an exception, matching + /// . + /// + Task CreateForCourseAsync(int courseId, CancellationToken cancellationToken = default); + + /// + /// An Octokit client for a token the caller already holds. A null or empty token yields an anonymous + /// client, which still works for public reads at GitHub's 60-requests-an-hour rate. + /// + IGitHubClient CreateForToken(string? token); +} + +/// +/// Builds the portal's Octokit clients. Every GitHub API call the portal makes goes through one of these — the +/// assignment flow, the webhook handlers and the chatops commands alike. +/// +/// Deliberately not routed through the named "github" : Octokit wants a +/// Func<HttpMessageHandler> rather than a configured client, and the named client's +/// BaseAddress and default headers would fight Octokit's own. That named client stays in use by +/// (the App-JWT bootstrap, which is not an API call) and by the +/// health checks. +/// +public sealed class CourseGitHubClientFactory : ICourseGitHubClientFactory +{ + /// + /// Carried over from github-monitor's client factory. Deliberately shorter than it looks like it + /// should be: a webhook delivery that takes longer than GitHub's own delivery timeout is already lost, so + /// failing fast beats hanging on to the request. + /// + private static readonly TimeSpan RequestTimeout = TimeSpan.FromSeconds(15); + + private static readonly ProductHeaderValue Product = new("ahk-portal", "1.0"); + + private readonly ICourseGitHubAppTokenProvider tokenProvider; + + public CourseGitHubClientFactory(ICourseGitHubAppTokenProvider tokenProvider) => this.tokenProvider = tokenProvider; + + public async Task CreateForCourseAsync(int courseId, CancellationToken cancellationToken = default) + { + var token = await tokenProvider.GetForCourseAsync(courseId, bypassCache: false, cancellationToken); + return token is null ? null : CreateForToken(token.Token); + } + + public IGitHubClient CreateForToken(string? token) + { + var credentials = string.IsNullOrWhiteSpace(token) + ? Credentials.Anonymous + : new Credentials(token); + + var connection = new Connection(Product, new InMemoryCredentialStore(credentials)); + var client = new GitHubClient(connection); + client.SetRequestTimeout(RequestTimeout); + + return client; + } +} diff --git a/ahk-backend/Ahk.Web.Services/GitHub/GitHubRepositoryService.cs b/ahk-backend/Ahk.Web.Services/GitHub/GitHubRepositoryService.cs index 231c922c..26c206bc 100644 --- a/ahk-backend/Ahk.Web.Services/GitHub/GitHubRepositoryService.cs +++ b/ahk-backend/Ahk.Web.Services/GitHub/GitHubRepositoryService.cs @@ -1,7 +1,5 @@ using System.Net; -using System.Net.Http.Headers; -using System.Net.Http.Json; -using System.Text.Json; +using Octokit; namespace Ahk.Web.Services.GitHub; @@ -47,216 +45,187 @@ public interface IGitHubRepositoryService } /// -/// The GitHub REST calls the assignment flow needs, over the shared named . Deliberately -/// raw HttpClient + System.Text.Json rather than Octokit: this is the idiom the portal already -/// uses (see Health/GitHubAccessHealthCheck) and a handful of endpoints does not justify a dependency. +/// The GitHub REST calls the assignment flow needs, over Octokit. +/// +/// The interface and its four record types are deliberately Octokit-free. They are narrow projections that keep +/// AssignmentInviteService and every test double away from Octokit's large, awkward-to-construct models, +/// and they are what lets AssignmentInviteTests mock this service strictly. /// /// Every method takes the caller's installation token explicitly rather than resolving a course itself, so the /// service stays a thin, testable transport with no ambient state. /// public sealed class GitHubRepositoryService : IGitHubRepositoryService { - private readonly IHttpClientFactory httpClientFactory; + private readonly ICourseGitHubClientFactory clientFactory; - public GitHubRepositoryService(IHttpClientFactory httpClientFactory) => this.httpClientFactory = httpClientFactory; + public GitHubRepositoryService(ICourseGitHubClientFactory clientFactory) => this.clientFactory = clientFactory; - public async Task GetUserAsync(string login, string? token, CancellationToken cancellationToken = default) + public Task GetUserAsync(string login, string? token, CancellationToken cancellationToken = default) { - using var client = CreateClient(token); - using var response = await client.GetAsync(Relative($"users/{Uri.EscapeDataString(login)}"), cancellationToken); - - if (response.StatusCode == HttpStatusCode.NotFound) - return null; - - await EnsureSuccessAsync(response, $"looking up the GitHub user '{login}'", cancellationToken); - - using var document = await ReadJsonAsync(response, cancellationToken); - return new GitHubUser( - document.RootElement.GetProperty("login").GetString() ?? login, - document.RootElement.GetProperty("id").GetInt64()); + // GET /users/{login} works unauthenticated; the token only lifts the rate limit from 60 to 5000/hour. + var client = clientFactory.CreateForToken(token); + + return ExecuteAsync( + $"looking up the GitHub user '{login}'", + async () => + { + var user = await client.User.Get(login); + return new GitHubUser(user.Login ?? login, user.Id); + }, + notFound: () => null); } - public async Task GetRepositoryAsync(string owner, string name, string token, CancellationToken cancellationToken = default) + public Task GetRepositoryAsync(string owner, string name, string token, CancellationToken cancellationToken = default) { - using var client = CreateClient(token); - using var response = await client.GetAsync(Relative($"repos/{Uri.EscapeDataString(owner)}/{Uri.EscapeDataString(name)}"), cancellationToken); - - if (response.StatusCode == HttpStatusCode.NotFound) - return null; - - await EnsureSuccessAsync(response, $"reading the repository '{owner}/{name}'", cancellationToken); + var client = clientFactory.CreateForToken(token); - using var document = await ReadJsonAsync(response, cancellationToken); - return ReadRepository(document.RootElement, $"{owner}/{name}"); + return ExecuteAsync( + $"reading the repository '{owner}/{name}'", + async () => ToRepository(await client.Repository.Get(owner, name), $"{owner}/{name}"), + notFound: () => null); } - public async Task GenerateFromTemplateAsync(string templateOwner, string templateName, string owner, string name, string token, CancellationToken cancellationToken = default) + public Task GenerateFromTemplateAsync(string templateOwner, string templateName, string owner, string name, string token, CancellationToken cancellationToken = default) { - using var client = CreateClient(token); + var client = clientFactory.CreateForToken(token); - // include_all_branches stays false: the student starts from the template's default branch, which is - // what the evaluator and the branch-protection rules assume. - var body = new + // include_all_branches is not sent, and GitHub defaults it to false: the student starts from the + // template's default branch, which is what the evaluator and the branch-protection rules assume. + var request = new NewRepositoryFromTemplate(name) { - owner, - name, - @private = true, - include_all_branches = false, + Owner = owner, + Private = true, }; - using var response = await client.PostAsJsonAsync( - Relative($"repos/{Uri.EscapeDataString(templateOwner)}/{Uri.EscapeDataString(templateName)}/generate"), - body, - cancellationToken); - - await EnsureSuccessAsync(response, $"creating '{owner}/{name}' from the template '{templateOwner}/{templateName}'", cancellationToken); - - using var document = await ReadJsonAsync(response, cancellationToken); - return ReadRepository(document.RootElement, $"{owner}/{name}"); + return ExecuteAsync( + $"creating '{owner}/{name}' from the template '{templateOwner}/{templateName}'", + async () => ToRepository(await client.Repository.Generate(templateOwner, templateName, request), $"{owner}/{name}")); } - public async Task EnsureActionsEnabledAsync(string owner, string name, string token, CancellationToken cancellationToken = default) + public Task EnsureActionsEnabledAsync(string owner, string name, string token, CancellationToken cancellationToken = default) { - using var client = CreateClient(token); - using var response = await client.PutAsJsonAsync( - Relative($"repos/{Uri.EscapeDataString(owner)}/{Uri.EscapeDataString(name)}/actions/permissions"), - new { enabled = true }, - cancellationToken); - - await EnsureSuccessAsync(response, $"enabling Actions on '{owner}/{name}'", cancellationToken); + var client = clientFactory.CreateForToken(token); + + // Octokit has no first-class client for the Actions permissions endpoint; Connection keeps it on the + // same authenticated client rather than opening a second transport for one call. + return ExecuteAsync( + $"enabling Actions on '{owner}/{name}'", + async () => + { + await client.Connection.Put( + new Uri($"repos/{Uri.EscapeDataString(owner)}/{Uri.EscapeDataString(name)}/actions/permissions", UriKind.Relative), + new { enabled = true }); + return true; + }); } - public async Task AddCollaboratorAsync(string owner, string name, string login, string token, CancellationToken cancellationToken = default) + public Task AddCollaboratorAsync(string owner, string name, string login, string token, CancellationToken cancellationToken = default) { - using var client = CreateClient(token); - using var response = await client.PutAsJsonAsync( - Relative($"repos/{Uri.EscapeDataString(owner)}/{Uri.EscapeDataString(name)}/collaborators/{Uri.EscapeDataString(login)}"), - new { permission = "push" }, - cancellationToken); - - await EnsureSuccessAsync(response, $"granting '{login}' access to '{owner}/{name}'", cancellationToken); - - // 204 means the login was added outright (they are already an organization member). 201 means an - // invitation was created and the repository stays invisible to them until they accept it. - if (response.StatusCode == HttpStatusCode.NoContent) - return new CollaboratorResult(InvitationCreated: false, InvitationId: null); - - using var document = await ReadJsonAsync(response, cancellationToken); - var id = document.RootElement.TryGetProperty("id", out var idElement) ? idElement.GetInt64() : (long?)null; - return new CollaboratorResult(InvitationCreated: true, InvitationId: id); + var client = clientFactory.CreateForToken(token); + + return ExecuteAsync( + $"granting '{login}' access to '{owner}/{name}'", + async () => + { + // GitHub answers 204 when the login was added outright (they are already an organization + // member) and 201 with the invitation when it was not. Octokit surfaces that as null vs a + // RepositoryInvitation, so the null check *is* the 204/201 distinction. + var invitation = await client.Repository.Collaborator.Add(owner, name, login, new CollaboratorRequest("push")); + + return invitation is null + ? new CollaboratorResult(InvitationCreated: false, InvitationId: null) + : new CollaboratorResult(InvitationCreated: true, InvitationId: invitation.Id); + }); } - public async Task IsCollaboratorAsync(string owner, string name, string login, string token, CancellationToken cancellationToken = default) + public Task IsCollaboratorAsync(string owner, string name, string login, string token, CancellationToken cancellationToken = default) { - using var client = CreateClient(token); - using var response = await client.GetAsync( - Relative($"repos/{Uri.EscapeDataString(owner)}/{Uri.EscapeDataString(name)}/collaborators/{Uri.EscapeDataString(login)}"), - cancellationToken); - - if (response.StatusCode is HttpStatusCode.NoContent or HttpStatusCode.OK) - return true; - - if (response.StatusCode == HttpStatusCode.NotFound) - return false; + var client = clientFactory.CreateForToken(token); - await EnsureSuccessAsync(response, $"checking whether '{login}' can access '{owner}/{name}'", cancellationToken); - return false; + return ExecuteAsync( + $"checking whether '{login}' can access '{owner}/{name}'", + () => client.Repository.Collaborator.IsCollaborator(owner, name, login), + notFound: () => false); } - public async Task FindInvitationAsync(string owner, string name, string login, string token, CancellationToken cancellationToken = default) + public Task FindInvitationAsync(string owner, string name, string login, string token, CancellationToken cancellationToken = default) { - using var client = CreateClient(token); - using var response = await client.GetAsync( - Relative($"repos/{Uri.EscapeDataString(owner)}/{Uri.EscapeDataString(name)}/invitations"), - cancellationToken); - - if (response.StatusCode == HttpStatusCode.NotFound) - return null; - - await EnsureSuccessAsync(response, $"listing invitations of '{owner}/{name}'", cancellationToken); - - using var document = await ReadJsonAsync(response, cancellationToken); - if (document.RootElement.ValueKind != JsonValueKind.Array) - return null; - - foreach (var element in document.RootElement.EnumerateArray()) - { - var invitee = element.TryGetProperty("invitee", out var inviteeElement) && inviteeElement.ValueKind == JsonValueKind.Object - ? inviteeElement.GetProperty("login").GetString() - : null; - - if (!string.Equals(invitee, login, StringComparison.OrdinalIgnoreCase)) - continue; - - // GitHub reports expiry itself. Never compute it here: the window is GitHub's policy to change, - // and a stale local constant would have the portal telling students something untrue. - var expired = element.TryGetProperty("expired", out var expiredElement) - && expiredElement.ValueKind == JsonValueKind.True; - - var createdAt = element.TryGetProperty("created_at", out var createdElement) - && createdElement.TryGetDateTimeOffset(out var parsed) - ? parsed - : (DateTimeOffset?)null; - - return new GitHubInvitation(element.GetProperty("id").GetInt64(), invitee, expired, createdAt); - } - - return null; + var client = clientFactory.CreateForToken(token); + + // Octokit's invitation client is keyed by repository *id*, which would cost an extra repository read + // per call. Connection keeps it to the one request the REST API actually needs. + return ExecuteAsync( + $"listing invitations of '{owner}/{name}'", + async () => + { + var response = await client.Connection.Get>( + new Uri($"repos/{Uri.EscapeDataString(owner)}/{Uri.EscapeDataString(name)}/invitations", UriKind.Relative), + parameters: null); + + var invitation = response.Body?.FirstOrDefault( + i => string.Equals(i.Invitee?.Login, login, StringComparison.OrdinalIgnoreCase)); + + if (invitation is null) + return null; + + // GitHub reports expiry itself. Never compute it here: the window is GitHub's policy to change, + // and a stale local constant would have the portal telling students something untrue. + return new GitHubInvitation(invitation.Id, invitation.Invitee?.Login, invitation.Expired, invitation.CreatedAt); + }, + notFound: () => null); } - public async Task DeleteInvitationAsync(string owner, string name, long invitationId, string token, CancellationToken cancellationToken = default) + public Task DeleteInvitationAsync(string owner, string name, long invitationId, string token, CancellationToken cancellationToken = default) { - using var client = CreateClient(token); - using var response = await client.DeleteAsync( - Relative($"repos/{Uri.EscapeDataString(owner)}/{Uri.EscapeDataString(name)}/invitations/{invitationId}"), - cancellationToken); - - // Already gone is the desired state, not a failure — the student may have accepted it meanwhile. - if (response.StatusCode == HttpStatusCode.NotFound) - return; - - await EnsureSuccessAsync(response, $"withdrawing invitation {invitationId} on '{owner}/{name}'", cancellationToken); + var client = clientFactory.CreateForToken(token); + + return ExecuteAsync( + $"withdrawing invitation {invitationId} on '{owner}/{name}'", + async () => + { + await client.Connection.Delete( + new Uri($"repos/{Uri.EscapeDataString(owner)}/{Uri.EscapeDataString(name)}/invitations/{invitationId}", UriKind.Relative)); + return true; + }, + // Already gone is the desired state, not a failure — the student may have accepted it meanwhile. + notFound: () => true); } - private static Uri Relative(string path) => new(path, UriKind.Relative); - - private static GitHubRepository ReadRepository(JsonElement element, string fallbackFullName) + private static GitHubRepository ToRepository(Repository repository, string fallbackFullName) { - var fullName = element.TryGetProperty("full_name", out var full) ? full.GetString() : null; - var htmlUrl = element.TryGetProperty("html_url", out var url) ? url.GetString() : null; - var isTemplate = element.TryGetProperty("is_template", out var template) && template.ValueKind == JsonValueKind.True; - var defaultBranch = element.TryGetProperty("default_branch", out var branch) ? branch.GetString() : null; + var fullName = string.IsNullOrEmpty(repository.FullName) ? fallbackFullName : repository.FullName; return new GitHubRepository( - fullName ?? fallbackFullName, - htmlUrl ?? $"https://github.com/{fullName ?? fallbackFullName}", - isTemplate, - defaultBranch); + fullName, + string.IsNullOrEmpty(repository.HtmlUrl) ? $"https://github.com/{fullName}" : repository.HtmlUrl, + repository.IsTemplate, + repository.DefaultBranch); } - private HttpClient CreateClient(string? token) + /// + /// Runs a GitHub call and translates Octokit's exceptions into , which + /// controllers surface as a 502 carrying GitHub's own explanation. turns a 404 + /// into a value instead, for the calls where "absent" is an answer rather than a failure. + /// + private static async Task ExecuteAsync(string operation, Func> call, Func? notFound = null) { - var client = httpClientFactory.CreateClient(GitHubApiDefaults.HttpClientName); - - // GET /users/{login} works unauthenticated; it just drops from 5000 to 60 requests an hour. - if (!string.IsNullOrWhiteSpace(token)) - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); - - return client; - } - - private static async Task ReadJsonAsync(HttpResponseMessage response, CancellationToken cancellationToken) - { - await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken); - return await JsonDocument.ParseAsync(stream, cancellationToken: cancellationToken); - } - - private static async Task EnsureSuccessAsync(HttpResponseMessage response, string operation, CancellationToken cancellationToken) - { - if (response.IsSuccessStatusCode) - return; - - var message = await GitHubApiDefaults.ReadErrorMessageAsync(response, cancellationToken); - throw new GitHubOperationException(operation, response.StatusCode, message); + try + { + return await call(); + } + catch (NotFoundException) when (notFound is not null) + { + return notFound(); + } + catch (ApiException ex) + { + throw new GitHubOperationException(operation, ex.StatusCode, ex.ApiError?.Message); + } + catch (OperationCanceledException ex) + { + // Octokit surfaces its own request timeout as a cancellation, which would otherwise look like the + // caller giving up rather than GitHub being slow. + throw new GitHubOperationException(operation, HttpStatusCode.GatewayTimeout, ex.Message); + } } } diff --git a/ahk-backend/Ahk.Web.Services/ServiceCollectionExtensions.cs b/ahk-backend/Ahk.Web.Services/ServiceCollectionExtensions.cs index 84cad879..1d36d0f2 100644 --- a/ahk-backend/Ahk.Web.Services/ServiceCollectionExtensions.cs +++ b/ahk-backend/Ahk.Web.Services/ServiceCollectionExtensions.cs @@ -34,8 +34,13 @@ public static IServiceCollection AddAhkServices(this IServiceCollection services } /// - /// The GitHub REST transport shared by the assignment flow: a named client based at api.github.com and the - /// per-course installation-token provider that authenticates it. + /// The GitHub transport: Octokit clients for every API call, plus the per-course installation-token + /// provider that authenticates them. + /// + /// The named "github" registered here is *not* the API transport. It backs + /// only 's App-JWT bootstrap (signing a JWT and exchanging it for + /// an installation token is not an API call, and converting it to Octokit would change the shape of the + /// permissions the health check reads). /// public static IServiceCollection AddAhkGitHubApi(this IServiceCollection services) { @@ -52,6 +57,7 @@ public static IServiceCollection AddAhkGitHubApi(this IServiceCollection service }); services.AddScoped(); + services.AddScoped(); services.AddScoped(); return services; From c3dd989ff3eb691f9410224e1b68e34f302ea1d8 Mon Sep 17 00:00:00 2001 From: Bence Kovari Date: Sun, 9 Aug 2026 01:42:53 +0200 Subject: [PATCH 11/19] feat(portal): receive GitHub webhooks at /api/integrations/github Ports github-monitor's webhook receiver and all ten of its handlers into the portal, so the reserved path stops answering 405 from the SPA fallback. The six Azure Storage queues are gone with it: the status-tracking handlers call ISubmissionEventService and the chatops handlers call IGradeService in-process, both of which already existed with no callers. Structural changes from the original, everything else verbatim (the bilingual warning strings are a student-facing interface): - Handlers are scoped DI registrations behind IGitHubWebhookHandler rather than reflectively activated types. ActivatorUtilities only ever existed to hand the Function's per-invocation ILogger to a handler. Registration order is the dispatch order and is kept identical. - Per-delivery state (course, delivery id, body, client, run threshold) moved onto GitHubWebhookContext, so handlers hold none. - ActionWorkflowRunHandler's threshold was a const 5 because a deployment served one course; it now reads CourseGitHubConfig.WorkflowRunThreshold. - The workflow payload types move out of `namespace Octokit` into our own. The day Octokit ships its own WorkflowRunEventPayload, that trick stops the build for reasons nobody would connect to this file. The load-bearing design point is that the webhook secret is per course, and the only thing identifying the course is repository.full_name inside the body - so an untrusted body must be parsed before it can be verified. Everything before the signature check is kept inert: one property read from a JsonDocument that is then dropped, two indexed reads, no writes, no GitHub calls, no body logging. A forged name just selects a different course's secret and fails the same 400. Benign cases (repo in no course, integration off) answer 202, not 4xx: GitHub colours non-2xx red in the delivery log, and during cutover an organization legitimately contains repositories that are not a course. Co-Authored-By: Claude Opus 5 --- .../Integrations/GitHubWebhookController.cs | 181 ++++++++++++++++ .../Ahk.Web.Server/Integrations/RawBody.cs | 20 ++ .../GitHubWebhooks/ConfigYamlParser.cs | 37 ++++ .../GitHubWebhooks/EventHandlerResult.cs | 22 ++ .../GitHubSignatureValidator.cs | 41 ++++ .../GitHubWebhooks/GitHubWebhookContext.cs | 38 ++++ .../GitHubWebhooks/GitHubWebhookDispatcher.cs | 67 ++++++ .../GitHubWebhooks/GradeCommentParser.cs | 66 ++++++ .../Handlers/ActionWorkflowRunHandler.cs | 79 +++++++ .../Handlers/BranchProtectionRuleHandler.cs | 49 +++++ .../GradeComment/CommentPayloadFacades.cs | 57 +++++ .../GradeComment/GradeCommandHandlerBase.cs | 141 ++++++++++++ .../GradeCommandIssueCommentHandler.cs | 31 +++ .../GradeCommandReviewCommentHandler.cs | 37 ++++ .../Handlers/IssueCommentEditDeleteHandler.cs | 39 ++++ .../PullRequestOpenDuplicateHandler.cs | 101 +++++++++ .../PullRequestReviewToAssigneeHandler.cs | 47 ++++ .../Handlers/RepositoryEventHandlerBase.cs | 204 ++++++++++++++++++ .../BranchCreateStatusTrackingHandler.cs | 54 +++++ .../PullRequestStatusTrackingHandler.cs | 60 ++++++ .../WorkflowRunStatusTrackingHandler.cs | 47 ++++ .../GitHubWebhooks/IGitHubWebhookHandler.cs | 28 +++ .../Payloads/WorkflowPayloads.cs | 31 +++ .../GitHubWebhooks/WebhookResult.cs | 19 ++ .../ServiceCollectionExtensions.cs | 30 +++ 25 files changed, 1526 insertions(+) create mode 100644 ahk-backend/Ahk.Web.Server/Integrations/GitHubWebhookController.cs create mode 100644 ahk-backend/Ahk.Web.Server/Integrations/RawBody.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/ConfigYamlParser.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/EventHandlerResult.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/GitHubSignatureValidator.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/GitHubWebhookContext.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/GitHubWebhookDispatcher.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/GradeCommentParser.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/ActionWorkflowRunHandler.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/BranchProtectionRuleHandler.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/GradeComment/CommentPayloadFacades.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/GradeComment/GradeCommandHandlerBase.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/GradeComment/GradeCommandIssueCommentHandler.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/GradeComment/GradeCommandReviewCommentHandler.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/IssueCommentEditDeleteHandler.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/PullRequestOpenDuplicateHandler.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/PullRequestReviewToAssigneeHandler.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/RepositoryEventHandlerBase.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/StatusTracking/BranchCreateStatusTrackingHandler.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/StatusTracking/PullRequestStatusTrackingHandler.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/StatusTracking/WorkflowRunStatusTrackingHandler.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/IGitHubWebhookHandler.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/Payloads/WorkflowPayloads.cs create mode 100644 ahk-backend/Ahk.Web.Services/GitHubWebhooks/WebhookResult.cs diff --git a/ahk-backend/Ahk.Web.Server/Integrations/GitHubWebhookController.cs b/ahk-backend/Ahk.Web.Server/Integrations/GitHubWebhookController.cs new file mode 100644 index 00000000..efbbc81d --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Integrations/GitHubWebhookController.cs @@ -0,0 +1,181 @@ +using System.Text.Json; +using Ahk.Web.Data; +using Ahk.Web.Server.CourseContext; +using Ahk.Web.Services.Courses; +using Ahk.Web.Services.GitHub; +using Ahk.Web.Services.GitHubWebhooks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace Ahk.Web.Server.Integrations; + +/// +/// Receives GitHub App webhook deliveries — the entry point ported from github-monitor's single Azure +/// Function. Anonymous by design: the X-Hub-Signature-256 HMAC is the authentication, and there is no +/// fallback authorization policy in Program.cs for it to fight. +/// +/// Kept out of the OpenAPI document: the SPA never calls this, and NSwag would emit a TypeScript client +/// for a byte-exact signed payload that no browser can produce. +/// +[ApiController] +[AllowAnonymous] +[Route("api/integrations/github")] +[ApiExplorerSettings(IgnoreApi = true)] +public sealed class GitHubWebhookController : ControllerBase +{ + /// GitHub caps webhook payloads at 25 MB. Bounds the work done before the signature is checked. + private const int MaxPayloadBytes = 25 * 1024 * 1024; + + private readonly ICourseResolutionService courses; + private readonly ICourseGitHubAppTokenProvider tokenProvider; + private readonly ICourseGitHubClientFactory clientFactory; + private readonly IGitHubWebhookDispatcher dispatcher; + private readonly CurrentCourseProvider currentCourse; + private readonly ApplicationDbContext db; + private readonly ILogger logger; + + public GitHubWebhookController( + ICourseResolutionService courses, + ICourseGitHubAppTokenProvider tokenProvider, + ICourseGitHubClientFactory clientFactory, + IGitHubWebhookDispatcher dispatcher, + CurrentCourseProvider currentCourse, + ApplicationDbContext db, + ILogger logger) + { + this.courses = courses; + this.tokenProvider = tokenProvider; + this.clientFactory = clientFactory; + this.dispatcher = dispatcher; + this.currentCourse = currentCourse; + this.db = db; + this.logger = logger; + } + + /// + /// Deliberately no [Consumes]: a webhook mistakenly configured as x-www-form-urlencoded + /// should get our explanatory 400 in the delivery log, not a bare framework 415. + /// + [HttpPost] + [RequestSizeLimit(MaxPayloadBytes)] + [ProducesResponseType(typeof(WebhookResult), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status202Accepted)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task Receive(CancellationToken cancellationToken) + { + var eventName = Request.Headers["X-GitHub-Event"].FirstOrDefault(); + var deliveryId = Request.Headers["X-GitHub-Delivery"].FirstOrDefault(); + var receivedSignature = Request.Headers["X-Hub-Signature-256"].FirstOrDefault(); + + logger.LogInformation( + "Webhook delivery: Delivery id = '{DeliveryId}', Event name = '{EventName}'", deliveryId, eventName); + + if (string.IsNullOrEmpty(eventName)) + return BadRequest(new { error = "X-GitHub-Event header missing" }); + + if (string.IsNullOrEmpty(receivedSignature)) + return BadRequest(new { error = "X-Hub-Signature-256 header missing" }); + + var requestBody = await RawBody.ReadAsync(Request, cancellationToken); + if (string.IsNullOrEmpty(requestBody)) + return BadRequest(new { error = "request body was empty" }); + + // The secret is per course, and the only thing in a delivery that identifies the course is the + // repository name inside the body — so an untrusted body must be parsed before it can be verified. + // Everything up to the signature check is therefore kept inert: one property is read and the document + // is dropped, and nothing is written, logged or called until the HMAC passes. + var repositoryFullName = TryReadRepositoryFullName(requestBody); + if (string.IsNullOrEmpty(repositoryFullName)) + return BadRequest(new { error = "no repository information in webhook payload" }); + + var course = await courses.ResolveByRepositoryAsync(repositoryFullName, cancellationToken); + if (course is null) + { + // 202 rather than 4xx: during cutover an organization legitimately contains repositories that are + // not a course, and a delivery log full of red trains administrators to stop reading it. + logger.LogInformation("Webhook delivery for '{Repository}' matches no course", repositoryFullName); + return Accepted(new { message = $"repository '{repositoryFullName}' is not mapped to a course" }); + } + + var config = await db.CourseGitHubConfigs.AsNoTracking() + .FirstOrDefaultAsync(g => g.CourseId == course.Id, cancellationToken); + + if (config is null) + return Accepted(new { message = $"GitHub integration is not configured for course '{course.Slug}'" }); + + if (!config.Enabled) + return Accepted(new { message = $"GitHub integration is turned off for course '{course.Slug}'" }); + + if (string.IsNullOrEmpty(config.GitHubWebhookSecret)) + return StatusCode(StatusCodes.Status500InternalServerError, new { error = "GitHub secret not configured" }); + + if (!GitHubSignatureValidator.IsSignatureValid(requestBody, receivedSignature, config.GitHubWebhookSecret)) + return BadRequest(new { error = "Payload signature not valid" }); + + // Past this point the body is trusted. + currentCourse.Set(course.Id); + + // The org-based lookup is used rather than the payload's installation.id: the course is resolved *by* + // organization, so the two are the same installation by construction, and deriving a credential from a + // payload field is a weaker path to the same answer. + var token = await tokenProvider.GetForCourseAsync(course.Id, bypassCache: false, cancellationToken); + if (token is null) + return StatusCode(StatusCodes.Status500InternalServerError, new { error = "GitHub App ID/Token not configured" }); + + var context = new GitHubWebhookContext + { + CourseId = course.Id, + GitHubEventName = eventName, + DeliveryId = deliveryId ?? string.Empty, + RequestBody = requestBody, + GitHubClient = clientFactory.CreateForToken(token.Token), + WorkflowRunThreshold = config.WorkflowRunThreshold, + }; + + logger.LogInformation("Webhook delivery accepted with Delivery id = '{DeliveryId}'", deliveryId); + + var webhookResult = new WebhookResult(); + try + { + await dispatcher.ProcessAsync(context, webhookResult, cancellationToken); + logger.LogInformation("Webhook delivery processed successfully with Delivery id = '{DeliveryId}'", deliveryId); + } +#pragma warning disable CA1031 // A handled delivery still answers 200; the failure is reported in the body. + catch (Exception ex) +#pragma warning restore CA1031 + { + webhookResult.LogError(ex, "Failed to handle webhook"); + logger.LogError(ex, "github-webhook failed with Delivery id = '{DeliveryId}'", deliveryId); + } + + return Ok(webhookResult); + } + + /// + /// Reads repository.full_name and nothing else out of an as-yet-unverified body. Returns null on any + /// malformed input — this runs before authentication, so it must not throw. + /// + private static string? TryReadRepositoryFullName(string requestBody) + { + try + { + using var document = JsonDocument.Parse(requestBody); + + if (document.RootElement.ValueKind != JsonValueKind.Object + || !document.RootElement.TryGetProperty("repository", out var repository) + || repository.ValueKind != JsonValueKind.Object + || !repository.TryGetProperty("full_name", out var fullName)) + { + return null; + } + + return fullName.GetString(); + } + catch (JsonException) + { + return null; + } + } +} diff --git a/ahk-backend/Ahk.Web.Server/Integrations/RawBody.cs b/ahk-backend/Ahk.Web.Server/Integrations/RawBody.cs new file mode 100644 index 00000000..401dc267 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Integrations/RawBody.cs @@ -0,0 +1,20 @@ +using System.Text; + +namespace Ahk.Web.Server.Integrations; + +/// +/// Reads a request body as the exact string that was signed. +/// +/// Both machine-to-machine schemes here (GitHub's X-Hub-Signature-256 and the CI callback's +/// X-Ahk-Sha256) compute their HMAC over the raw bytes, so the body must not be round-tripped through +/// model binding first. The controllers therefore declare no [FromBody] parameter, MVC never touches the +/// stream, and this reads it once — no EnableBuffering anywhere in the pipeline. +/// +internal static class RawBody +{ + public static async Task ReadAsync(HttpRequest request, CancellationToken cancellationToken = default) + { + using var reader = new StreamReader(request.Body, Encoding.UTF8, detectEncodingFromByteOrderMarks: false, leaveOpen: true); + return await reader.ReadToEndAsync(cancellationToken); + } +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/ConfigYamlParser.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/ConfigYamlParser.cs new file mode 100644 index 00000000..6b69b3c3 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/ConfigYamlParser.cs @@ -0,0 +1,37 @@ +using System.Text.RegularExpressions; + +namespace Ahk.Web.Services.GitHubWebhooks; + +/// +/// Reads the enabled flag out of a repository's .github/ahk-monitor.yml. Ported verbatim from +/// github-monitor: this is the opt-in gate that keeps the portal from acting on every repository in an +/// organization, and its exact accepted spellings (enabled, enabled: true, yes, 1) +/// are what existing course templates rely on. +/// +internal static partial class ConfigYamlParser +{ + [GeneratedRegex(@"^enabled:?\s*(?\w+)?", RegexOptions.IgnoreCase | RegexOptions.Multiline)] + private static partial Regex EnabledRegex(); + + public static bool IsEnabled(string? fileContent) + { + // Missing file -> disabled. + if (string.IsNullOrEmpty(fileContent)) + return false; + + // File content does not match -> disabled. + var m = EnabledRegex().Match(fileContent); + if (!m.Success) + return false; + + var value = m.Groups["value"]; + + // No "true" or other part, just "enabled" -> ok. + if (!value.Success) + return true; + + return value.Value.Equals("true", StringComparison.OrdinalIgnoreCase) + || value.Value.Equals("yes", StringComparison.OrdinalIgnoreCase) + || value.Value.Equals("1", StringComparison.OrdinalIgnoreCase); + } +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/EventHandlerResult.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/EventHandlerResult.cs new file mode 100644 index 00000000..11d7fc11 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/EventHandlerResult.cs @@ -0,0 +1,22 @@ +namespace Ahk.Web.Services.GitHubWebhooks; + +/// +/// One handler's verdict on one delivery. The prefixes ("payload error", "no action needed", …) are what shows +/// up in the delivery log, so they are kept verbatim from github-monitor. +/// +public sealed class EventHandlerResult +{ + public EventHandlerResult(string result) => this.Result = result; + + public string Result { get; } + + public static EventHandlerResult PayloadError(string message) => new($"payload error: {message}"); + + public static EventHandlerResult NoActionNeeded(string message) => new($"no action needed: {message}"); + + public static EventHandlerResult ActionPerformed(string message) => new($"action performed: {message}"); + + public static EventHandlerResult EventNotOfInterest(string action) => new($"action not of interest: {action}"); + + public static EventHandlerResult Disabled(string? message = null) => new(message is null ? "event handler disabled" : $"event handler disabled: {message}"); +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/GitHubSignatureValidator.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/GitHubSignatureValidator.cs new file mode 100644 index 00000000..3905ccc3 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/GitHubSignatureValidator.cs @@ -0,0 +1,41 @@ +using System.Globalization; +using System.Security.Cryptography; +using System.Text; + +namespace Ahk.Web.Services.GitHubWebhooks; + +/// +/// Validates GitHub's X-Hub-Signature-256 header against the course's webhook secret. Ported verbatim +/// from github-monitor/.../Helpers/GitHubSignatureValidator.cs; the ASCII key encoding is GitHub's +/// scheme, not an oversight, and must not be "fixed" to UTF-8. +/// +public static class GitHubSignatureValidator +{ + public static bool IsSignatureValid(string requestBody, string? receivedSignature, string? secret) + { + if (string.IsNullOrEmpty(receivedSignature) || string.IsNullOrEmpty(secret)) + return false; + + var key = Encoding.ASCII.GetBytes(secret); + var requestBytes = Encoding.UTF8.GetBytes(requestBody ?? string.Empty); + + using var hmac = new HMACSHA256(key); + var hash = hmac.ComputeHash(requestBytes); + var expectedSignature = "sha256=" + ToHexString(hash); + + // Compare length first, do not even try to compare content if these do not match. + if (receivedSignature.Length != expectedSignature.Length) + return false; + + return receivedSignature.Equals(expectedSignature, StringComparison.Ordinal); + } + + private static string ToHexString(byte[] bytes) + { + var builder = new StringBuilder(bytes.Length * 2); + foreach (var b in bytes) + builder.AppendFormat(CultureInfo.InvariantCulture, "{0:x2}", b); + + return builder.ToString(); + } +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/GitHubWebhookContext.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/GitHubWebhookContext.cs new file mode 100644 index 00000000..edab8443 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/GitHubWebhookContext.cs @@ -0,0 +1,38 @@ +using Octokit; + +namespace Ahk.Web.Services.GitHubWebhooks; + +/// +/// Everything one webhook delivery carries into the handlers. All per-delivery state lives here rather than on +/// the handler, which is what lets handlers be ordinary scoped DI registrations instead of the reflectively +/// activated, mutable objects github-monitor needed. +/// +/// The body has already been signature-verified by the time a context exists; handlers may trust it. +/// +public sealed class GitHubWebhookContext +{ + /// + /// The course the delivery's repository belongs to. Always passed explicitly into services — nothing on the + /// webhook path may rely on the ambient ICurrentCourseProvider, because the EF course filter matches + /// nothing when no course is set. + /// + public required int CourseId { get; init; } + + /// The X-GitHub-Event header. + public required string GitHubEventName { get; init; } + + /// The X-GitHub-Delivery header; empty when absent. Makes status-event writes idempotent. + public required string DeliveryId { get; init; } + + /// The raw, signature-verified request body. + public required string RequestBody { get; init; } + + /// Authenticated as the course's GitHub App installation. + public required IGitHubClient GitHubClient { get; init; } + + /// + /// From CourseGitHubConfig.WorkflowRunThreshold. Was a compile-time constant of 5 in + /// github-monitor, since each deployment served exactly one course. + /// + public required int WorkflowRunThreshold { get; init; } +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/GitHubWebhookDispatcher.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/GitHubWebhookDispatcher.cs new file mode 100644 index 00000000..2e97ffcb --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/GitHubWebhookDispatcher.cs @@ -0,0 +1,67 @@ +using Microsoft.Extensions.Logging; + +namespace Ahk.Web.Services.GitHubWebhooks; + +public interface IGitHubWebhookDispatcher +{ + Task ProcessAsync(GitHubWebhookContext context, WebhookResult result, CancellationToken cancellationToken = default); +} + +/// +/// Routes a delivery to every handler subscribed to its event name. Port of +/// github-monitor/.../Services/EventDispatch/EventDispatchService.cs. +/// +/// Two things carried over deliberately: handlers run sequentially in registration order (some +/// post comments and the order they appear in matters), and each is wrapped in its own try/catch so one +/// failing handler does not cost the others their run. The reflective +/// ActivatorUtilities.CreateInstance is gone — it only existed to hand the Azure Function's +/// per-invocation logger to a handler, which plain DI does for free. +/// +internal sealed class GitHubWebhookDispatcher : IGitHubWebhookDispatcher +{ + private readonly IReadOnlyList handlers; + private readonly ILogger logger; + + public GitHubWebhookDispatcher(IEnumerable handlers, ILogger logger) + { + this.handlers = handlers.ToList(); + this.logger = logger; + } + + public async Task ProcessAsync(GitHubWebhookContext context, WebhookResult result, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(context); + ArgumentNullException.ThrowIfNull(result); + + var forEvent = handlers + .Where(h => string.Equals(h.GitHubEventName, context.GitHubEventName, StringComparison.OrdinalIgnoreCase)) + .ToList(); + + if (forEvent.Count == 0) + { + result.LogInfo($"Event {context.GitHubEventName} is not of interest"); + logger.LogInformation("Event {EventName} is not of interest", context.GitHubEventName); + return; + } + + foreach (var handler in forEvent) + { + var name = handler.GetType().Name; + logger.LogInformation("Event {EventName} being handled by {Handler}", context.GitHubEventName, name); + + try + { + var handlerResult = await handler.ExecuteAsync(context, cancellationToken); + logger.LogInformation("{Handler} result: {Result}", name, handlerResult.Result); + result.LogInfo($"{name} -> {handlerResult.Result}"); + } +#pragma warning disable CA1031 // One handler's failure must not cost the others their run. + catch (Exception ex) +#pragma warning restore CA1031 + { + logger.LogError(ex, "{Handler} execution failed", name); + result.LogError(ex, $"{name} -> exception"); + } + } + } +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/GradeCommentParser.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/GradeCommentParser.cs new file mode 100644 index 00000000..94f6b5d3 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/GradeCommentParser.cs @@ -0,0 +1,66 @@ +using System.Globalization; +using System.Text.RegularExpressions; + +namespace Ahk.Web.Services.GitHubWebhooks; + +/// +/// Parses the teacher's /ahk ok chatops command out of a comment body. Ported verbatim from +/// github-monitor/.../Helpers/GradeCommentParser.cs. +/// +/// /ahk ok alone confirms the automated evaluation; /ahk ok 5 3.5 0 overrides it, the +/// numbers mapping positionally onto exercises. Both comma and dot are accepted as the decimal separator, +/// because Hungarian keyboards produce the comma. +/// +/// Two behaviours that look like bugs and are not: the loop does not break, so in a multi-line +/// comment the last matching line wins; and an unparseable number becomes +/// rather than throwing. +/// +internal sealed partial class GradeCommentParser +{ + [GeneratedRegex(@"^/ahk ok($|(\s.*))", RegexOptions.IgnoreCase | RegexOptions.Singleline)] + private static partial Regex CommandRegex(); + + [GeneratedRegex(@"[0-9]+([,\.][0-9]{1,3})?", RegexOptions.IgnoreCase | RegexOptions.Singleline)] + private static partial Regex GradesRegex(); + + public GradeCommentParser(string? value) + { + this.Grades = Array.Empty(); + + if (string.IsNullOrEmpty(value)) + return; + + var lines = value.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); + foreach (var line in lines) + { + var m = CommandRegex().Match(line); + if (m.Success) + { + this.IsMatch = true; + this.Grades = GetGrades(m.Value); + } + } + } + + public bool IsMatch { get; } + + public IReadOnlyList Grades { get; } + + public bool HasGrades => IsMatch && Grades.Count > 0; + + private static IReadOnlyList GetGrades(string value) + => GradesRegex().Matches(value).Select(m => ParseNum(m.Value)).ToArray(); + + private static double ParseNum(string value) + { + // Try to parse as an int, or as a double with a decimal point. + if (double.TryParse(value, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var d1)) + return d1; + + // Replace commas with a decimal point. + if (double.TryParse(value.Replace(",", ".", StringComparison.OrdinalIgnoreCase), NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var d2)) + return d2; + + return double.NaN; + } +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/ActionWorkflowRunHandler.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/ActionWorkflowRunHandler.cs new file mode 100644 index 00000000..377ece7b --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/ActionWorkflowRunHandler.cs @@ -0,0 +1,79 @@ +using Ahk.Web.Services.GitHubWebhooks.Payloads; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; +using Octokit; + +namespace Ahk.Web.Services.GitHubWebhooks.Handlers; + +/// +/// Warns a student who has run the automated evaluation more times than the course allows. Ported from +/// github-monitor/.../EventHandlers/ActionWorkflowRunHandler.cs. +/// +/// The one behavioural change in the port: the threshold was a compile-time constant of 5, because each +/// deployment served exactly one course. It now comes from CourseGitHubConfig.WorkflowRunThreshold. +/// +public sealed class ActionWorkflowRunHandler : RepositoryEventHandlerBase +{ + private const string WarningText = ":exclamation: **You triggered too many automated evaluations; extra evaluations are penalized. Túl sok automata értékelést futtattál; az extra futtatások pontlevonással járnak.** "; + + public ActionWorkflowRunHandler(IMemoryCache cache, ILogger logger) + : base(cache, logger) + { + } + + public override string GitHubEventName => "workflow_run"; + + protected override async Task ExecuteCoreAsync(GitHubWebhookContext context, WorkflowRunEventPayload payload, CancellationToken cancellationToken) + { + if (payload.Action is null || !payload.Action.Equals("completed", StringComparison.OrdinalIgnoreCase)) + return EventHandlerResult.EventNotOfInterest(payload.Action ?? string.Empty); + + if (string.IsNullOrEmpty(payload.Sender?.Login)) + return EventHandlerResult.PayloadError("missing actor user"); + + if (await IsUserOrganizationMemberAsync(context, payload, payload.Sender.Login)) + return EventHandlerResult.NoActionNeeded("workflow_run ok, not triggered by student"); + + var workflowRuns = await CountWorkflowRunsAsync(context, payload.Repository.Owner.Login, payload.Repository.Name, payload.Sender.Login); + if (workflowRuns <= context.WorkflowRunThreshold) + return EventHandlerResult.NoActionNeeded("workflow_run ok, has less then threshold"); + + var prNum = await GetMostRecentPullRequestAsync(context, payload); + if (prNum.HasValue) + await context.GitHubClient.Issue.Comment.Create(payload.Repository.Id, prNum.Value, WarningText); + + return EventHandlerResult.ActionPerformed("workflow_run warning, threshold exceeded"); + } + + /// + /// Kept as a raw Connection call rather than Octokit's Actions.Workflows.Runs client. What is + /// wanted is GitHub's own total_count for the filtered query; Octokit's paginating client would + /// count differently, and a silent change here changes a student's grade. + /// + private static async Task CountWorkflowRunsAsync(GitHubWebhookContext context, string owner, string repo, string actor) + { + var response = await context.GitHubClient.Connection.Get( + uri: new Uri($"repos/{owner}/{repo}/actions/runs", UriKind.Relative), + parameters: new Dictionary + { + ["actor"] = actor, + ["status"] = "completed", + }, + accepts: AcceptHeaders.StableVersionJson); + + return response.Body.TotalCount; + } + + private static async Task GetMostRecentPullRequestAsync(GitHubWebhookContext context, WorkflowRunEventPayload payload) + { + var list = await context.GitHubClient.PullRequest.GetAllForRepository( + payload.Repository.Id, new PullRequestRequest { State = ItemStateFilter.All }); + + return list.OrderByDescending(p => p.UpdatedAt).FirstOrDefault()?.Number; + } + + internal sealed class ListWorkflowRunsResponse + { + public int TotalCount { get; set; } + } +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/BranchProtectionRuleHandler.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/BranchProtectionRuleHandler.cs new file mode 100644 index 00000000..07e42291 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/BranchProtectionRuleHandler.cs @@ -0,0 +1,49 @@ +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; +using Octokit; + +namespace Ahk.Web.Services.GitHubWebhooks.Handlers; + +/// +/// Applies the course's branch rules when a branch is created: the default branch requires a review (so the +/// student cannot merge their own pull request), every other branch is left alone beyond disabling force push. +/// Ported from github-monitor/.../EventHandlers/BranchProtectionRuleHandler.cs. +/// +public sealed class BranchProtectionRuleHandler : RepositoryEventHandlerBase +{ + public BranchProtectionRuleHandler(IMemoryCache cache, ILogger logger) + : base(cache, logger) + { + } + + public override string GitHubEventName => "create"; + + protected override async Task ExecuteCoreAsync(GitHubWebhookContext context, CreateEventPayload payload, CancellationToken cancellationToken) + { + // StringValue rather than the RefType enum: Octokit throws on ref types it does not know, and a new + // one appearing must not take the handler down. + if (!payload.RefType.StringValue.Equals("branch", StringComparison.OrdinalIgnoreCase)) + return EventHandlerResult.NoActionNeeded($"create event for ref {payload.RefType} is not of interest"); + + await context.GitHubClient.Repository.Branch.UpdateBranchProtection( + payload.Repository.Id, payload.Ref, GetBranchProtectionSettingsUpdate(payload.Ref, payload.Repository.DefaultBranch)); + + return EventHandlerResult.ActionPerformed("branch protection rule applied"); + } + + private static BranchProtectionSettingsUpdate GetBranchProtectionSettingsUpdate(string branchName, string repositoryDefaultBranch) + { + // For default: prohibits the merge request into default to be merged. + // For other branches: disables force push. + return new BranchProtectionSettingsUpdate( + requiredStatusChecks: null, + requiredPullRequestReviews: GetBranchProtectionRequiredReviewsUpdate(branchName, repositoryDefaultBranch), + restrictions: null, + enforceAdmins: false); + } + + private static BranchProtectionRequiredReviewsUpdate? GetBranchProtectionRequiredReviewsUpdate(string branchName, string repositoryDefaultBranch) + => branchName.Equals(repositoryDefaultBranch, StringComparison.OrdinalIgnoreCase) + ? new BranchProtectionRequiredReviewsUpdate(false, false, 1) // Prohibits the student from merging the pull request. + : null; +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/GradeComment/CommentPayloadFacades.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/GradeComment/CommentPayloadFacades.cs new file mode 100644 index 00000000..022bb66f --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/GradeComment/CommentPayloadFacades.cs @@ -0,0 +1,57 @@ +using Octokit; + +namespace Ahk.Web.Services.GitHubWebhooks.Handlers.GradeComment; + +/// +/// The parts of a comment the grading command needs, regardless of whether it arrived as an issue comment or +/// as a pull request review. Lets one base class serve both events. +/// +public interface ICommentPayload + where T : ActivityPayload +{ + T Payload { get; } + + Repository Repository { get; } + + int PullRequestNumber { get; } + + string CommentingUser { get; } + + string CommentHtmlUrl { get; } + + string CommentBody { get; } +} + +internal sealed class IssueCommentPayloadFacade : ICommentPayload +{ + public IssueCommentPayloadFacade(IssueCommentPayload payload) => this.Payload = payload; + + public IssueCommentPayload Payload { get; } + + public Repository Repository => Payload.Repository; + + public int PullRequestNumber => Payload.Issue.Number; + + public string CommentingUser => Payload.Comment.User.Login; + + public string CommentHtmlUrl => Payload.Comment.HtmlUrl; + + public string CommentBody => Payload.Comment.Body; +} + +internal sealed class ReviewCommentPayloadFacade : ICommentPayload +{ + public ReviewCommentPayloadFacade(PullRequestReviewEventPayload payload) => this.Payload = payload; + + public PullRequestReviewEventPayload Payload { get; } + + public Repository Repository => Payload.Repository; + + public int PullRequestNumber => Payload.PullRequest.Number; + + public string CommentingUser => Payload.Review.User.Login; + + public string CommentHtmlUrl => Payload.Review.HtmlUrl; + + public string CommentBody => Payload.Review.Body; +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/GradeComment/GradeCommandHandlerBase.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/GradeComment/GradeCommandHandlerBase.cs new file mode 100644 index 00000000..81e18bc9 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/GradeComment/GradeCommandHandlerBase.cs @@ -0,0 +1,141 @@ +using Ahk.Web.Services.Grading; +using Ahk.Web.Services.Grading.Dto; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; +using Octokit; + +namespace Ahk.Web.Services.GitHubWebhooks.Handlers.GradeComment; + +/// +/// The /ahk ok chatops command: a teacher comment that approves a student's pull request, merges it, and +/// records the grade. Ported from github-monitor/.../EventHandlers/GradeComment/GradeCommandHandlerBase.cs. +/// +/// The one structural change: where the original enqueued a message onto Azure Queue Storage for +/// grade-management to pick up, this calls directly. A failure is therefore visible +/// in the delivery log instead of disappearing into a queue — and because the 👍 reaction is added only after +/// the grade write, its presence remains an honest signal that the whole command succeeded. +/// +public abstract class GradeCommandHandlerBase : RepositoryEventHandlerBase + where T : ActivityPayload +{ + private const string WarningText = ":exclamation: **@{} is not allowed to do that. @{} Ez nem engedelyezett szamodra.**"; + + private readonly IGradeService grades; + + protected GradeCommandHandlerBase(IGradeService grades, IMemoryCache cache, ILogger logger) + : base(cache, logger) + { + this.grades = grades; + } + + protected abstract Task HandleReactionAsync(GitHubWebhookContext context, ICommentPayload payload, ReactionType reactionType); + + protected async Task ProcessCommentAsync(GitHubWebhookContext context, ICommentPayload payload, CancellationToken cancellationToken) + { + ArgumentNullException.ThrowIfNull(payload); + + var gradeCommand = new GradeCommentParser(payload.CommentBody); + if (!gradeCommand.IsMatch) + return EventHandlerResult.NoActionNeeded("not recognized as command"); + + // Only organization members may grade. A student posting "/ahk ok" in their own repository gets told so. + if (!await IsAllowedAsync(context, payload)) + return await HandleUserNotAllowedAsync(context, payload); + + var pr = await GetPullRequestAsync(context, payload); + if (pr is null) + return await HandleNotPrAsync(context, payload); + + await HandleApproveAsync(context, payload, pr); + await HandleStoreGradeAsync(context, payload, gradeCommand, pr, cancellationToken); + + await HandleReactionAsync(context, payload, ReactionType.Plus1); + return EventHandlerResult.ActionPerformed($"comment operation to grade done; grades: {string.Join(" ", gradeCommand.Grades)}"); + } + + private static async Task GetPullRequestAsync(GitHubWebhookContext context, ICommentPayload payload) + { + try + { + return await context.GitHubClient.PullRequest.Get(payload.Repository.Id, payload.PullRequestNumber); + } + catch (NotFoundException) + { + return null; + } + } + + private async Task HandleStoreGradeAsync(GitHubWebhookContext context, ICommentPayload payload, GradeCommentParser gradeCommand, PullRequest pr, CancellationToken cancellationToken) + { + var neptun = await GetNeptunAsync(context, payload.Repository.Id, pr.Head.Ref); + Logger.LogInformation("storing grades for {Neptun}", neptun); + + if (gradeCommand.HasGrades) + { + await grades.SetGradeAsync( + context.CourseId, + new SetGradeInput + { + Neptun = neptun ?? string.Empty, + Repository = payload.Repository.FullName, + PrNumber = pr.Number, + PrUrl = pr.HtmlUrl, + Actor = payload.CommentingUser, + Origin = payload.CommentHtmlUrl, + Results = gradeCommand.Grades, + }, + cancellationToken); + } + else + { + await grades.ConfirmAutoGradeAsync( + context.CourseId, + new ConfirmAutoGradeInput + { + Neptun = neptun ?? string.Empty, + Repository = payload.Repository.FullName, + PrNumber = pr.Number, + PrUrl = pr.HtmlUrl, + Actor = payload.CommentingUser, + Origin = payload.CommentHtmlUrl, + }, + cancellationToken); + } + } + + private async Task HandleApproveAsync(GitHubWebhookContext context, ICommentPayload payload, PullRequest pr) + { + if (pr.State.Value == ItemState.Open && pr.Mergeable == true) + { + Logger.LogInformation("PR is being merged"); + await context.GitHubClient.PullRequest.Review.Create( + payload.Repository.Id, payload.PullRequestNumber, new PullRequestReviewCreate { Event = PullRequestReviewEvent.Approve }); + await context.GitHubClient.PullRequest.Merge(payload.Repository.Id, payload.PullRequestNumber, new MergePullRequest()); + } + else + { + Logger.LogInformation("PR is not mergable"); + } + } + + private async Task HandleNotPrAsync(GitHubWebhookContext context, ICommentPayload payload) + { + await HandleReactionAsync(context, payload, ReactionType.Confused); + return EventHandlerResult.ActionPerformed("comment operation to grade not called for PR"); + } + + private async Task HandleUserNotAllowedAsync(GitHubWebhookContext context, ICommentPayload payload) + { + await HandleReactionAsync(context, payload, ReactionType.Confused); + + var comment = WarningText.Replace("{}", payload.CommentingUser, StringComparison.OrdinalIgnoreCase); + await context.GitHubClient.Issue.Comment.Create(payload.Repository.Id, payload.PullRequestNumber, comment); + + return EventHandlerResult.ActionPerformed("comment operation to grade not allowed for user"); + } + + private Task IsAllowedAsync(GitHubWebhookContext context, ICommentPayload payload) + => payload.Repository.Owner.Type != AccountType.Organization + ? Task.FromResult(false) + : IsOrganizationMemberAsync(context, payload.Repository.Owner.Login, payload.CommentingUser); +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/GradeComment/GradeCommandIssueCommentHandler.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/GradeComment/GradeCommandIssueCommentHandler.cs new file mode 100644 index 00000000..df74e1c0 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/GradeComment/GradeCommandIssueCommentHandler.cs @@ -0,0 +1,31 @@ +using Ahk.Web.Services.Grading; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; +using Octokit; + +namespace Ahk.Web.Services.GitHubWebhooks.Handlers.GradeComment; + +/// /ahk ok posted as an ordinary pull request comment. The common case. +public sealed class GradeCommandIssueCommentHandler : GradeCommandHandlerBase +{ + public GradeCommandIssueCommentHandler(IGradeService grades, IMemoryCache cache, ILogger logger) + : base(grades, cache, logger) + { + } + + public override string GitHubEventName => "issue_comment"; + + protected override async Task ExecuteCoreAsync(GitHubWebhookContext context, IssueCommentPayload payload, CancellationToken cancellationToken) + { + if (payload.Issue is null) + return EventHandlerResult.PayloadError("no issue information in webhook payload"); + + if (payload.Action.Equals("created", StringComparison.OrdinalIgnoreCase)) + return await ProcessCommentAsync(context, new IssueCommentPayloadFacade(payload), cancellationToken); + + return EventHandlerResult.EventNotOfInterest(payload.Action); + } + + protected override Task HandleReactionAsync(GitHubWebhookContext context, ICommentPayload payload, ReactionType reactionType) + => context.GitHubClient.Reaction.IssueComment.Create(payload.Repository.Id, payload.Payload.Comment.Id, new NewReaction(reactionType)); +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/GradeComment/GradeCommandReviewCommentHandler.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/GradeComment/GradeCommandReviewCommentHandler.cs new file mode 100644 index 00000000..9248516b --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/GradeComment/GradeCommandReviewCommentHandler.cs @@ -0,0 +1,37 @@ +using Ahk.Web.Services.Grading; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; +using Octokit; + +namespace Ahk.Web.Services.GitHubWebhooks.Handlers.GradeComment; + +/// /ahk ok written in the body of a submitted pull request review rather than as a comment. +public sealed class GradeCommandReviewCommentHandler : GradeCommandHandlerBase +{ + public GradeCommandReviewCommentHandler(IGradeService grades, IMemoryCache cache, ILogger logger) + : base(grades, cache, logger) + { + } + + public override string GitHubEventName => "pull_request_review"; + + protected override async Task ExecuteCoreAsync(GitHubWebhookContext context, PullRequestReviewEventPayload payload, CancellationToken cancellationToken) + { + if (payload.Review is null) + return EventHandlerResult.PayloadError("no review information in webhook payload"); + + if (payload.Action.Equals("submitted", StringComparison.OrdinalIgnoreCase)) + return await ProcessCommentAsync(context, new ReviewCommentPayloadFacade(payload), cancellationToken); + + return EventHandlerResult.EventNotOfInterest(payload.Action); + } + + /// + /// Deliberately does nothing. Reacting to a *review* returns an error for a GitHub App: the documentation + /// says pull-request read/write should be enough, and it is not. Carried over from + /// github-monitor, where the same attempt was made and reverted — so a teacher grading through a + /// review gets no 👍, only the grade. + /// + protected override Task HandleReactionAsync(GitHubWebhookContext context, ICommentPayload payload, ReactionType reactionType) + => Task.CompletedTask; +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/IssueCommentEditDeleteHandler.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/IssueCommentEditDeleteHandler.cs new file mode 100644 index 00000000..30d6e554 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/IssueCommentEditDeleteHandler.cs @@ -0,0 +1,39 @@ +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; +using Octokit; + +namespace Ahk.Web.Services.GitHubWebhooks.Handlers; + +/// +/// Leaves a visible trace when somebody edits or deletes another person's comment — the audit trail of a +/// graded pull request is part of the evaluation. Editing your own comment is fine. Ported from +/// github-monitor/.../EventHandlers/IssueCommentEditDeleteHandler.cs. +/// +public sealed class IssueCommentEditDeleteHandler : RepositoryEventHandlerBase +{ + private const string WarningText = ":exclamation: **An issue comment was deleted / edited. Egy megjegyzes torolve vagy modositva lett.**"; + + public IssueCommentEditDeleteHandler(IMemoryCache cache, ILogger logger) + : base(cache, logger) + { + } + + public override string GitHubEventName => "issue_comment"; + + protected override async Task ExecuteCoreAsync(GitHubWebhookContext context, IssueCommentPayload payload, CancellationToken cancellationToken) + { + if (payload.Issue is null) + return EventHandlerResult.PayloadError("no issue information in webhook payload"); + + if (payload.Action.Equals("edited", StringComparison.OrdinalIgnoreCase) || payload.Action.Equals("deleted", StringComparison.OrdinalIgnoreCase)) + { + if (payload.Sender is not null && payload.Comment?.User is not null && payload.Sender.Login == payload.Comment.User.Login) + return EventHandlerResult.NoActionNeeded($"comment action {payload.Action} by {payload.Sender.Login} allowed, referencing own comment"); + + await context.GitHubClient.Issue.Comment.Create(payload.Repository.Id, payload.Issue.Number, WarningText); + return EventHandlerResult.ActionPerformed("comment action resulting in warning"); + } + + return EventHandlerResult.EventNotOfInterest(payload.Action); + } +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/PullRequestOpenDuplicateHandler.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/PullRequestOpenDuplicateHandler.cs new file mode 100644 index 00000000..6ba0b066 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/PullRequestOpenDuplicateHandler.cs @@ -0,0 +1,101 @@ +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; +using Octokit; + +namespace Ahk.Web.Services.GitHubWebhooks.Handlers; + +/// +/// Warns when a student opens more than one pull request for the same work — several open at once, or a new +/// one after a teacher already closed an earlier one. Ported from +/// github-monitor/.../EventHandlers/PullRequestOpenDuplicateHandler.cs. +/// +/// ⚠️ The slowest handler by some way: it lists every pull request in the repository and, for each closed one, +/// its issue events. On a repository with a long history this alone can approach GitHub's delivery timeout. +/// +public sealed class PullRequestOpenDuplicateHandler : RepositoryEventHandlerBase +{ + private const string WarningText = ":exclamation: **You have multiple pull requests. Tobb pull request-et nyitottal.** {} \n\n"; + + public PullRequestOpenDuplicateHandler(IMemoryCache cache, ILogger logger) + : base(cache, logger) + { + } + + public override string GitHubEventName => "pull_request"; + + protected override async Task ExecuteCoreAsync(GitHubWebhookContext context, PullRequestEventPayload payload, CancellationToken cancellationToken) + { + if (payload.PullRequest is null) + return EventHandlerResult.PayloadError("no pull request information in webhook payload"); + + if (!payload.Action.Equals("opened", StringComparison.OrdinalIgnoreCase)) + return EventHandlerResult.EventNotOfInterest(payload.Action); + + var repositoryPrs = await context.GitHubClient.PullRequest.GetAllForRepository( + payload.Repository.Id, new PullRequestRequest { State = ItemStateFilter.All }); + + if (repositoryPrs.Count <= 1) + return EventHandlerResult.NoActionNeeded("pull request open is ok, there are no other PRs"); + + var (handledOpen, resultOpen) = await HandleAnyOpenPrsAsync(context, payload, repositoryPrs); + var (handledClosed, resultClosed) = await HandleAnyClosedPrsAsync(context, payload, repositoryPrs); + + return !handledOpen && !handledClosed + ? EventHandlerResult.NoActionNeeded($"{resultOpen}; {resultClosed}") + : EventHandlerResult.ActionPerformed($"{resultOpen}; {resultClosed}"); + } + + private static string GetWarningText(int currentPrNumber, IEnumerable foundPrNumbers) + { + var prReferencesText = string.Join( + " ", + foundPrNumbers.Union(new[] { currentPrNumber }).Distinct().OrderBy(num => num).Select(n => $"#{n}").ToArray()); + + return WarningText.Replace("{}", prReferencesText, StringComparison.OrdinalIgnoreCase); + } + + private static async Task<(bool HasProblem, string ResultText)> HandleAnyOpenPrsAsync( + GitHubWebhookContext context, PullRequestEventPayload payload, IReadOnlyCollection repositoryPrs) + { + var openPrs = repositoryPrs.Where(otherPr => otherPr.State == ItemState.Open).ToList(); + if (openPrs.Count <= 1) + return (false, "pull request open is ok, there are no other open PRs"); + + var warningText = GetWarningText(payload.PullRequest.Number, openPrs.Select(pr => pr.Number)); + foreach (var openPullRequest in openPrs) + await context.GitHubClient.Issue.Comment.Create(payload.Repository.Id, openPullRequest.Number, warningText); + + return (true, "pull request open handled with multiple open PRs"); + } + + private static async Task<(bool HasProblem, string ResultText)> HandleAnyClosedPrsAsync( + GitHubWebhookContext context, PullRequestEventPayload payload, IReadOnlyCollection repositoryPrs) + { + var closedPrs = repositoryPrs.Where(otherPr => otherPr.State == ItemState.Closed).ToList(); + if (closedPrs.Count == 0) + return (false, "pull request open is ok, there are no other closed PRs"); + + var prsClosedByNotStudent = new List(); + foreach (var otherClosedPr in closedPrs) + { + if (await IsPrClosedByNotStudentAsync(context, payload, otherClosedPr)) + prsClosedByNotStudent.Add(otherClosedPr.Number); + } + + if (prsClosedByNotStudent.Count == 0) + return (false, "pull request open is ok, there are no other evaluated PRs"); + + var warningText = GetWarningText(payload.PullRequest.Number, prsClosedByNotStudent); + await context.GitHubClient.Issue.Comment.Create(payload.Repository.Id, payload.Number, warningText); + + return (true, "pull request open handled with already closed PRs"); + } + + private static async Task IsPrClosedByNotStudentAsync(GitHubWebhookContext context, PullRequestEventPayload payload, PullRequest pr) + { + var issueEvents = await context.GitHubClient.Issue.Events.GetAllForIssue(payload.Repository.Id, pr.Number); + + // A PR the student opened and somebody else closed is one a teacher already evaluated. + return issueEvents.Any(e => e.Event.Value == EventInfoState.Closed && e.Actor?.Id != pr.User.Id); + } +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/PullRequestReviewToAssigneeHandler.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/PullRequestReviewToAssigneeHandler.cs new file mode 100644 index 00000000..84297bbd --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/PullRequestReviewToAssigneeHandler.cs @@ -0,0 +1,47 @@ +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; +using Octokit; + +namespace Ahk.Web.Services.GitHubWebhooks.Handlers; + +/// +/// Mirrors a requested reviewer onto the pull request's assignee, so the teacher dashboard's "who is reviewing +/// this" column is populated by the act of requesting a review. Ported from +/// github-monitor/.../EventHandlers/PullRequestReviewToAssigneeHandler.cs. +/// +public sealed class PullRequestReviewToAssigneeHandler : RepositoryEventHandlerBase +{ + public PullRequestReviewToAssigneeHandler(IMemoryCache cache, ILogger logger) + : base(cache, logger) + { + } + + public override string GitHubEventName => "pull_request"; + + protected override async Task ExecuteCoreAsync(GitHubWebhookContext context, PullRequestEventPayload payload, CancellationToken cancellationToken) + { + if (payload.PullRequest is null) + return EventHandlerResult.PayloadError("no pull request information in webhook payload"); + + if (!payload.Action.Equals("review_requested", StringComparison.OrdinalIgnoreCase)) + return EventHandlerResult.EventNotOfInterest(payload.Action); + + if (payload.PullRequest.RequestedReviewers is null || payload.PullRequest.RequestedReviewers.Count == 0) + return EventHandlerResult.PayloadError("no requested reviewer in webhook payload"); + + if (IsPrAssignedToReviewer(payload)) + return EventHandlerResult.NoActionNeeded("pull request review_requested is ok, assignee is present"); + + await context.GitHubClient.Issue.Assignee.AddAssignees( + payload.Repository.Owner.Login, payload.Repository.Name, payload.PullRequest.Number, GetUsersToAssign(payload)); + + return EventHandlerResult.ActionPerformed("pull request review_requested handled, assignee set"); + } + + private static AssigneesUpdate GetUsersToAssign(PullRequestEventPayload payload) + => new(payload.PullRequest.RequestedReviewers.Select(r => r.Login).ToList()); + + private static bool IsPrAssignedToReviewer(PullRequestEventPayload payload) + => payload.PullRequest.Assignee is not null + && payload.PullRequest.RequestedReviewers.Any(r => r.Id == payload.PullRequest.Assignee.Id); +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/RepositoryEventHandlerBase.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/RepositoryEventHandlerBase.cs new file mode 100644 index 00000000..7dd659d5 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/RepositoryEventHandlerBase.cs @@ -0,0 +1,204 @@ +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; +using Octokit; +using Octokit.Internal; + +namespace Ahk.Web.Services.GitHubWebhooks.Handlers; + +/// +/// Base for every handler that acts on a repository. Port of +/// github-monitor/.../EventHandlers/RepositoryEventBase.cs, with the GitHub client and the delivery's +/// identity moved onto so the handler itself holds no state. +/// +/// Two behaviours are inherited by everything that derives from this and must not be bypassed: payload +/// deserialization with its four distinct error messages, and the .github/ahk-monitor.yml opt-in gate. +/// +public abstract class RepositoryEventHandlerBase : IGitHubWebhookHandler + where TPayload : ActivityPayload +{ + /// + /// How long a repository's opt-in answer is remembered. Long, because it is asked on every delivery and the + /// answer almost never changes — with the consequence that enabling a repository can take up to + /// half a day to be noticed. Restarting the application is the only faster flush. + /// + private static readonly TimeSpan EnabledCacheDuration = TimeSpan.FromHours(12); + + private static readonly TimeSpan NeptunCacheDuration = TimeSpan.FromHours(12); + + private static readonly TimeSpan OrganizationMemberCacheDuration = TimeSpan.FromHours(1); + + protected RepositoryEventHandlerBase(IMemoryCache cache, ILogger logger) + { + this.Cache = cache; + this.Logger = logger; + } + + public abstract string GitHubEventName { get; } + + protected ILogger Logger { get; } + + protected IMemoryCache Cache { get; } + + public async Task ExecuteAsync(GitHubWebhookContext context, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(context); + + if (!TryParsePayload(context.RequestBody, out var payload, out var errorResult)) + return errorResult; + + if (!await IsEnabledForRepositoryAsync(context, payload)) + { + Logger.LogInformation("no ahk-monitor.yml or disabled"); + return EventHandlerResult.Disabled("no ahk-monitor.yml or disabled"); + } + + return await ExecuteCoreAsync(context, payload, cancellationToken); + } + + protected abstract Task ExecuteCoreAsync(GitHubWebhookContext context, TPayload payload, CancellationToken cancellationToken); + + protected bool TryParsePayload(string requestBody, out TPayload payload, out EventHandlerResult errorResult) + { + payload = null!; + + if (string.IsNullOrEmpty(requestBody)) + { + errorResult = EventHandlerResult.PayloadError("request body was empty"); + Logger.LogError("request body was empty"); + return false; + } + + try + { + payload = new SimpleJsonSerializer().Deserialize(requestBody); + } +#pragma warning disable CA1031 // Any deserialization failure is reported to the delivery log, never thrown. + catch (Exception ex) +#pragma warning restore CA1031 + { + errorResult = EventHandlerResult.PayloadError($"request body deserialization failed: {ex.Message}"); + Logger.LogError(ex, "request body deserialization failed"); + return false; + } + + if (payload is null) + { + errorResult = EventHandlerResult.PayloadError("parsed payload was null or empty"); + Logger.LogError("parsed payload was null or empty"); + return false; + } + + if (payload.Repository is null) + { + errorResult = EventHandlerResult.PayloadError("no repository information in webhook payload"); + Logger.LogError("no repository information in webhook payload"); + return false; + } + + errorResult = null!; + return true; + } + + /// + /// The student's Neptun code, read from neptun.txt on the given branch. Null when the file is + /// missing — a repository whose owner never filled it in still gets its events recorded, just without a + /// student attached. + /// + protected Task GetNeptunAsync(GitHubWebhookContext context, long repositoryId, string branchName) + => Cache.GetOrCreateAsync( + key: $"neptuntxtfile{repositoryId}{branchName}", + factory: async cacheEntry => + { + var value = await GetNeptunTxtFileContentAsync(context, repositoryId, branchName); + cacheEntry.SetValue(value); + cacheEntry.SetAbsoluteExpiration(NeptunCacheDuration); + return value; + }); + + /// + /// Whether a login belongs to the repository's organization — the portal's definition of "is staff, not a + /// student". Non-organization repositories always answer false. + /// + protected Task IsUserOrganizationMemberAsync(GitHubWebhookContext context, TPayload payload, string username) + { + ArgumentNullException.ThrowIfNull(payload); + + if (payload.Repository.Owner.Type != AccountType.Organization) + return Task.FromResult(false); + + return IsOrganizationMemberAsync(context, payload.Repository.Owner.Login, username); + } + + protected Task IsOrganizationMemberAsync(GitHubWebhookContext context, string organization, string username) + => Cache.GetOrCreateAsync( + key: $"githubisorgmember{organization}{username}", + factory: async cacheEntry => + { + var isMember = await CheckOrganizationMemberAsync(context, organization, username); + cacheEntry.SetValue(isMember); + cacheEntry.SetAbsoluteExpiration(OrganizationMemberCacheDuration); + return isMember; + }); + + /// + /// The opt-in gate. A repository is acted on only when its default branch carries + /// .github/ahk-monitor.yml with enabled: true — otherwise every event from it is ignored. + /// Cached per repository id, which is globally unique, so no course qualifier is needed in the key. + /// + private Task IsEnabledForRepositoryAsync(GitHubWebhookContext context, TPayload payload) + => Cache.GetOrCreateAsync( + key: $"ahkmonitorisenabledinrepo{payload.Repository.Id}", + factory: async cacheEntry => + { + var isEnabled = await GetConfigIsEnabledInRepositoryAsync(context, payload); + cacheEntry.SetValue(isEnabled); + cacheEntry.SetAbsoluteExpiration(EnabledCacheDuration); + return isEnabled; + }); + + private static async Task GetConfigIsEnabledInRepositoryAsync(GitHubWebhookContext context, TPayload payload) + { + try + { + var contents = await context.GitHubClient.Repository.Content.GetAllContentsByRef( + payload.Repository.Id, ".github/ahk-monitor.yml", payload.Repository.DefaultBranch); + + if (contents.Count == 0) + return false; + + return ConfigYamlParser.IsEnabled(contents[0].Content); + } + catch (NotFoundException) + { + return false; + } + } + + private static async Task GetNeptunTxtFileContentAsync(GitHubWebhookContext context, long repositoryId, string branchName) + { + try + { + var contents = await context.GitHubClient.Repository.Content.GetAllContentsByRef(repositoryId, "neptun.txt", branchName); + if (contents.Count == 0) + return null; + + return contents[0].Content?.Trim(); + } + catch (NotFoundException) + { + return null; + } + } + + private static async Task CheckOrganizationMemberAsync(GitHubWebhookContext context, string organization, string username) + { + try + { + return await context.GitHubClient.Organization.Member.CheckMember(organization, username); + } + catch (NotFoundException) + { + return false; + } + } +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/StatusTracking/BranchCreateStatusTrackingHandler.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/StatusTracking/BranchCreateStatusTrackingHandler.cs new file mode 100644 index 00000000..123f3c76 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/StatusTracking/BranchCreateStatusTrackingHandler.cs @@ -0,0 +1,54 @@ +using Ahk.Web.Data.Entities; +using Ahk.Web.Services.StatusTracking; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; +using Octokit; + +namespace Ahk.Web.Services.GitHubWebhooks.Handlers.StatusTracking; + +/// +/// Records branch creation in the submission event log. Ported from +/// github-monitor/.../EventHandlers/StatusTracking/BranchCreateStatusTrackingHandler.cs. +/// +/// The two outcomes are mutually exclusive, which is what keeps the one-status-event-per-delivery +/// invariant intact for the create event. +/// +public sealed class BranchCreateStatusTrackingHandler : RepositoryEventHandlerBase, IStatusEventWriter +{ + private readonly ISubmissionEventService events; + + public BranchCreateStatusTrackingHandler(ISubmissionEventService events, IMemoryCache cache, ILogger logger) + : base(cache, logger) + { + this.events = events; + } + + public override string GitHubEventName => "create"; + + protected override async Task ExecuteCoreAsync(GitHubWebhookContext context, CreateEventPayload payload, CancellationToken cancellationToken) + { + if (!payload.RefType.Equals(RefType.Branch)) + return EventHandlerResult.EventNotOfInterest($"branch create ignored for RefType: {payload.RefType}, Ref: {payload.Ref}"); + + // Repository creation is recognised here rather than from the dedicated `repository` event: at that + // point the repository is still empty and carries no ahk-monitor.yml, so the opt-in gate would reject + // it. Creation of the default branch is the first moment the repository is recognisable as ours. + var isRepositoryCreate = payload.Ref.Equals(payload.Repository.DefaultBranch, StringComparison.OrdinalIgnoreCase); + + SubmissionEvent submissionEvent = isRepositoryCreate + ? new RepositoryCreatedEvent() + : new BranchCreatedEvent { Branch = payload.Ref }; + + submissionEvent.GitHubDeliveryId = NullIfEmpty(context.DeliveryId); + submissionEvent.Timestamp = DateTimeOffset.UtcNow; + + var recorded = await events.RecordAsync(context.CourseId, payload.Repository.FullName, submissionEvent, cancellationToken: cancellationToken); + if (!recorded) + return EventHandlerResult.NoActionNeeded("redelivery, event already recorded"); + + return EventHandlerResult.ActionPerformed( + isRepositoryCreate ? "repository create lifecycle handled" : "branch create lifecycle handled"); + } + + internal static string? NullIfEmpty(string? value) => string.IsNullOrEmpty(value) ? null : value; +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/StatusTracking/PullRequestStatusTrackingHandler.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/StatusTracking/PullRequestStatusTrackingHandler.cs new file mode 100644 index 00000000..653028a7 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/StatusTracking/PullRequestStatusTrackingHandler.cs @@ -0,0 +1,60 @@ +using Ahk.Web.Services.StatusTracking; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; +using Octokit; +using PullRequestStatusEvent = Ahk.Web.Data.Entities.PullRequestEvent; + +namespace Ahk.Web.Services.GitHubWebhooks.Handlers.StatusTracking; + +/// +/// Records pull request lifecycle events. The status projection reads the latest action per pull request +/// number, so the four actions tracked here are exactly the ones that change what a teacher sees. Ported from +/// github-monitor/.../EventHandlers/StatusTracking/PullRequestStatusTrackingHandler.cs. +/// +public sealed class PullRequestStatusTrackingHandler : RepositoryEventHandlerBase, IStatusEventWriter +{ + private readonly ISubmissionEventService events; + + public PullRequestStatusTrackingHandler(ISubmissionEventService events, IMemoryCache cache, ILogger logger) + : base(cache, logger) + { + this.events = events; + } + + public override string GitHubEventName => "pull_request"; + + protected override async Task ExecuteCoreAsync(GitHubWebhookContext context, PullRequestEventPayload payload, CancellationToken cancellationToken) + { + if (payload.PullRequest is null) + return EventHandlerResult.PayloadError("no pull request information in webhook payload"); + + if (!payload.Action.Equals("opened", StringComparison.OrdinalIgnoreCase) + && !payload.Action.Equals("assigned", StringComparison.OrdinalIgnoreCase) + && !payload.Action.Equals("review_requested", StringComparison.OrdinalIgnoreCase) + && !payload.Action.Equals("closed", StringComparison.OrdinalIgnoreCase)) + { + return EventHandlerResult.EventNotOfInterest(payload.Action); + } + + var neptun = await GetNeptunAsync(context, payload.Repository.Id, payload.PullRequest.Head.Ref); + + var submissionEvent = new PullRequestStatusEvent + { + Number = payload.PullRequest.Number, + Action = payload.Action, + HtmlUrl = payload.PullRequest.HtmlUrl, + Neptun = neptun, + Assignees = payload.PullRequest.Assignees?.Select(u => u.Login).ToList() ?? new List(), + GitHubDeliveryId = BranchCreateStatusTrackingHandler.NullIfEmpty(context.DeliveryId), + Timestamp = DateTimeOffset.UtcNow, + }; + + // The neptun is passed on as well, not just stored on the event: it is what links the submission to a + // student row, and a pull request is usually the first place it becomes known. + var recorded = await events.RecordAsync(context.CourseId, payload.Repository.FullName, submissionEvent, neptun, cancellationToken); + if (!recorded) + return EventHandlerResult.NoActionNeeded("redelivery, event already recorded"); + + return EventHandlerResult.ActionPerformed("pull request lifecycle handled"); + } +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/StatusTracking/WorkflowRunStatusTrackingHandler.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/StatusTracking/WorkflowRunStatusTrackingHandler.cs new file mode 100644 index 00000000..c01331e2 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Handlers/StatusTracking/WorkflowRunStatusTrackingHandler.cs @@ -0,0 +1,47 @@ +using Ahk.Web.Services.GitHubWebhooks.Payloads; +using Ahk.Web.Services.StatusTracking; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; +using WorkflowRunStatusEvent = Ahk.Web.Data.Entities.WorkflowRunEvent; + +namespace Ahk.Web.Services.GitHubWebhooks.Handlers.StatusTracking; + +/// +/// Records each completed evaluation run, which is what the dashboard's run count and last-conclusion columns +/// project over. Ported from +/// github-monitor/.../EventHandlers/StatusTracking/WorkflowRunStatusTrackingHandler.cs. +/// +public sealed class WorkflowRunStatusTrackingHandler : RepositoryEventHandlerBase, IStatusEventWriter +{ + private readonly ISubmissionEventService events; + + public WorkflowRunStatusTrackingHandler(ISubmissionEventService events, IMemoryCache cache, ILogger logger) + : base(cache, logger) + { + this.events = events; + } + + public override string GitHubEventName => "workflow_run"; + + protected override async Task ExecuteCoreAsync(GitHubWebhookContext context, WorkflowEventPayload payload, CancellationToken cancellationToken) + { + if (payload.WorkflowRun is null) + return EventHandlerResult.PayloadError("no workflow run information in webhook payload"); + + if (payload.Action is null || !payload.Action.Equals("completed", StringComparison.OrdinalIgnoreCase)) + return EventHandlerResult.EventNotOfInterest(payload.Action ?? string.Empty); + + var submissionEvent = new WorkflowRunStatusEvent + { + Conclusion = payload.WorkflowRun.Conclusion, + GitHubDeliveryId = BranchCreateStatusTrackingHandler.NullIfEmpty(context.DeliveryId), + Timestamp = DateTimeOffset.UtcNow, + }; + + var recorded = await events.RecordAsync(context.CourseId, payload.Repository.FullName, submissionEvent, cancellationToken: cancellationToken); + if (!recorded) + return EventHandlerResult.NoActionNeeded("redelivery, event already recorded"); + + return EventHandlerResult.ActionPerformed("workflow_run lifecycle handled"); + } +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/IGitHubWebhookHandler.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/IGitHubWebhookHandler.cs new file mode 100644 index 00000000..d78155df --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/IGitHubWebhookHandler.cs @@ -0,0 +1,28 @@ +namespace Ahk.Web.Services.GitHubWebhooks; + +/// +/// One rule enforced, or one fact recorded, in response to a GitHub webhook event. Handlers are registered in +/// DI and selected by ; several may subscribe to the same event and each runs +/// independently, so one throwing does not stop the others. +/// +public interface IGitHubWebhookHandler +{ + /// The X-GitHub-Event name this handler subscribes to, e.g. pull_request. + string GitHubEventName { get; } + + Task ExecuteAsync(GitHubWebhookContext context, CancellationToken cancellationToken = default); +} + +/// +/// Marks a handler that appends to the submission event log. +/// +/// ⚠️ SubmissionEvent.GitHubDeliveryId is globally unique, but one delivery fans out to several +/// handlers — so at most one handler per event name may write a status event, or the second +/// write is silently dropped as a redelivery (and would violate the unique index on SQL Server). The invariant +/// is asserted by WebhookHandlerRegistrationTests; if you need a second writer for an event, key the +/// delivery id per handler first. +/// +[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1040:Avoid empty interfaces", Justification = "A marker is the point: it is what the registration test can see without running a handler.")] +public interface IStatusEventWriter +{ +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Payloads/WorkflowPayloads.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Payloads/WorkflowPayloads.cs new file mode 100644 index 00000000..bfbd316c --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/Payloads/WorkflowPayloads.cs @@ -0,0 +1,31 @@ +using Octokit; + +namespace Ahk.Web.Services.GitHubWebhooks.Payloads; + +/// +/// The workflow_run payload, as much of it as the run-count rule needs. +/// +/// Octokit has no type for this event. github-monitor declared its equivalents inside +/// namespace Octokit so they looked native; that is a landmine for the next Octokit upgrade (the day +/// Octokit ships its own WorkflowRunEventPayload, the project stops compiling for reasons nobody will +/// connect to this file), so they live in our own namespace here. Octokit's +/// binds by convention, not by namespace, so nothing else changes. +/// +public class WorkflowRunEventPayload : ActivityPayload +{ + public string? Action { get; set; } +} + +/// The workflow_run payload including the run's conclusion, for the status event log. +public class WorkflowEventPayload : ActivityPayload +{ + public string? Action { get; set; } + + public WorkflowRun? WorkflowRun { get; set; } +} + +/// An Actions workflow run, as much of it as the status projection needs. +public class WorkflowRun +{ + public string? Conclusion { get; set; } +} diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/WebhookResult.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/WebhookResult.cs new file mode 100644 index 00000000..a2cf516b --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/WebhookResult.cs @@ -0,0 +1,19 @@ +using System.Diagnostics.CodeAnalysis; + +namespace Ahk.Web.Services.GitHubWebhooks; + +/// +/// What each handler made of one delivery, returned as the webhook's response body. This is what an +/// administrator reads in the GitHub App's Advanced → Recent Deliveries tab, which is the only +/// diagnostic surface GitHub offers — so the message strings are a user interface and are kept verbatim from +/// github-monitor. +/// +public sealed class WebhookResult +{ + [SuppressMessage("Design", "CA1002:Do not expose generic lists", Justification = "Result object is JSON serialized.")] + public List Messages { get; } = new(); + + public void LogInfo(string message) => Messages.Add(message); + + public void LogError(Exception ex, string message) => Messages.Add(message + ": " + ex?.ToString()); +} diff --git a/ahk-backend/Ahk.Web.Services/ServiceCollectionExtensions.cs b/ahk-backend/Ahk.Web.Services/ServiceCollectionExtensions.cs index 1d36d0f2..02a0d24c 100644 --- a/ahk-backend/Ahk.Web.Services/ServiceCollectionExtensions.cs +++ b/ahk-backend/Ahk.Web.Services/ServiceCollectionExtensions.cs @@ -2,6 +2,10 @@ using Ahk.Web.Services.Assignments; using Ahk.Web.Services.Courses; using Ahk.Web.Services.GitHub; +using Ahk.Web.Services.GitHubWebhooks; +using Ahk.Web.Services.GitHubWebhooks.Handlers; +using Ahk.Web.Services.GitHubWebhooks.Handlers.GradeComment; +using Ahk.Web.Services.GitHubWebhooks.Handlers.StatusTracking; using Ahk.Web.Services.Grading; using Ahk.Web.Services.Health; using Ahk.Web.Services.StatusTracking; @@ -24,6 +28,7 @@ public static IServiceCollection AddAhkServices(this IServiceCollection services services.AddScoped(); services.AddAhkGitHubApi(); + services.AddAhkGitHubWebhooks(); services.AddScoped(); services.AddScoped(); services.AddScoped(); @@ -63,6 +68,31 @@ public static IServiceCollection AddAhkGitHubApi(this IServiceCollection service return services; } + /// + /// The GitHub webhook receiver: the dispatcher plus every handler, ported from github-monitor. + /// + /// Registration order is the dispatch order and is kept identical to that app's + /// Startup.registerEventHandlers — DI hands an IEnumerable<T> back in registration + /// order, which is why the explicit config builder it used is not needed here. + /// + public static IServiceCollection AddAhkGitHubWebhooks(this IServiceCollection services) + { + services.AddScoped(); + + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + + return services; + } + /// /// Registers the course health checks and the service that runs them. Adding a check to the admin /// dashboard is one line here plus the class itself — the service discovers checks through DI. From e507edc7a6a4555bd5259b55db1bd419449b32a9 Mon Sep 17 00:00:00 2001 From: Bence Kovari Date: Sun, 9 Aug 2026 01:43:07 +0200 Subject: [PATCH 12/19] feat(portal): accept CI evaluation results at /api/integrations/evaluation-result Ports grade-management's evaluation-result function, the last of the three write-side entry points. HmacSha256Validator, the DTO and the validation order are verbatim ports: publish-results-pr is a Go client running inside student repositories that are updated on their own schedule, so this is a wire contract, and the error strings end up in student build logs. Two things deliberately left as they are rather than "fixed": - Unknown JSON members stay tolerated. The Go client sends imageFiles, which has never had a counterpart here. - [Required] on the nested taskName is not actually enforced, because Validator.TryValidateObject does not recurse into collections. Enforcing it would start failing student builds that pass today. New in the portal: the course comes from the callback token - the authenticated credential - not from the caller-supplied repository name. A mismatch between the two is logged as a warning rather than rejected, since it means a course is using another course's token and the grade is about to land in the wrong place. IDateTimeProvider is replaced by TimeProvider, registered in Program.cs, so the ten-minute clock-skew window stays testable. Co-Authored-By: Claude Opus 5 --- .../Dto/EvaluationResultRequest.cs | 67 ++++++ .../EvaluationResultController.cs | 211 ++++++++++++++++++ ahk-backend/Ahk.Web.Server/Program.cs | 6 + .../Integrations/HmacSha256Validator.cs | 56 +++++ 4 files changed, 340 insertions(+) create mode 100644 ahk-backend/Ahk.Web.Server/Integrations/Dto/EvaluationResultRequest.cs create mode 100644 ahk-backend/Ahk.Web.Server/Integrations/EvaluationResultController.cs create mode 100644 ahk-backend/Ahk.Web.Services/Integrations/HmacSha256Validator.cs diff --git a/ahk-backend/Ahk.Web.Server/Integrations/Dto/EvaluationResultRequest.cs b/ahk-backend/Ahk.Web.Server/Integrations/Dto/EvaluationResultRequest.cs new file mode 100644 index 00000000..4301f782 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Integrations/Dto/EvaluationResultRequest.cs @@ -0,0 +1,67 @@ +using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; + +namespace Ahk.Web.Server.Integrations.Dto; + +/// +/// The evaluation result posted by publish-results-pr. A verbatim port of grade-management's +/// AhkProcessResult, property names and validation attributes included: this is a wire contract with a +/// Go client running inside student repositories, and those repositories are updated on their own schedule. +/// +/// ⚠️ Unknown members are tolerated on purpose. The Go client also sends imageFiles, which has no +/// counterpart here and never had one. Do not turn on JsonUnmappedMemberHandling.Disallow. +/// +public sealed class EvaluationResultRequest +{ + [JsonPropertyName("gitHubRepoName")] + [Required] + [StringLength(200, MinimumLength = 1)] + public string GitHubRepoName { get; set; } = string.Empty; + + [JsonPropertyName("gitHubBranch")] + public string? GitHubBranch { get; set; } + + [JsonPropertyName("gitHubCommitHash")] + public string? GitHubCommitHash { get; set; } + + /// Absent rather than zero when there is no pull request — the Go client marks it omitempty. + [JsonPropertyName("gitHubPullRequestNum")] + public int? GitHubPullRequestNum { get; set; } + + [JsonPropertyName("neptunCode")] + [Required] + [StringLength(100, MinimumLength = 1)] + public string NeptunCode { get; set; } = string.Empty; + + [JsonPropertyName("result")] + public EvaluationTaskResultRequest[]? Result { get; set; } + + [JsonPropertyName("origin")] + public string? Origin { get; set; } +} + +/// +/// One task line from result.txt. +/// +/// ⚠️ The [Required] on is not actually enforced, because +/// Validator.TryValidateObject does not recurse into collection elements. That was true in +/// grade-management too, and it is left alone deliberately: a stricter server here would start failing student +/// builds that pass today. +/// +public sealed class EvaluationTaskResultRequest +{ + [JsonPropertyName("exerciseName")] + public string? ExerciseName { get; set; } + + [JsonPropertyName("taskName")] + [Required] + [StringLength(100, MinimumLength = 1)] + public string TaskName { get; set; } = string.Empty; + + [JsonPropertyName("points")] + [Required] + public double Points { get; set; } + + [JsonPropertyName("comment")] + public string? Comment { get; set; } +} diff --git a/ahk-backend/Ahk.Web.Server/Integrations/EvaluationResultController.cs b/ahk-backend/Ahk.Web.Server/Integrations/EvaluationResultController.cs new file mode 100644 index 00000000..d01bd715 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server/Integrations/EvaluationResultController.cs @@ -0,0 +1,211 @@ +using System.ComponentModel.DataAnnotations; +using System.Globalization; +using System.Text.Json; +using Ahk.Web.Server.CourseContext; +using Ahk.Web.Server.Integrations.Dto; +using Ahk.Web.Services.Courses; +using Ahk.Web.Services.Grading; +using Ahk.Web.Services.Grading.Dto; +using Ahk.Web.Services.Integrations; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http.Extensions; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Net.Http.Headers; + +namespace Ahk.Web.Server.Integrations; + +/// +/// Receives an automated evaluation result from the GitHub Action that runs in a student's repository — +/// the port of grade-management's evaluation-result function. +/// +/// ⚠️ The caller signs the request URL, so this route's public address is part of the contract: +/// https://ahk.aut.bme.hu/api/integrations/evaluation-result, https, no trailing slash. It must match the +/// action's AHK_APPURL exactly (case aside, which both sides lower). UseForwardedHeaders running +/// first in the pipeline is what makes yield the public URL behind IIS. +/// See docs/ci-callback.md. +/// +/// The Go client treats any non-2xx as fatal and fails the student's build, so the failure modes here are +/// deliberately limited to genuine misconfiguration. +/// +[ApiController] +[AllowAnonymous] +[Route("api/integrations/evaluation-result")] +[ApiExplorerSettings(IgnoreApi = true)] +public sealed class EvaluationResultController : ControllerBase +{ + /// How far the caller's clock may drift. Carried over unchanged; GitHub-hosted runners are UTC. + private static readonly TimeSpan MaxClockSkew = TimeSpan.FromMinutes(10); + + private static readonly JsonSerializerOptions PayloadOptions = new() { PropertyNameCaseInsensitive = true }; + + private readonly IWebhookTokenService tokens; + private readonly ICourseResolutionService courses; + private readonly IGradeService grades; + private readonly CurrentCourseProvider currentCourse; + private readonly TimeProvider timeProvider; + private readonly ILogger logger; + + public EvaluationResultController( + IWebhookTokenService tokens, + ICourseResolutionService courses, + IGradeService grades, + CurrentCourseProvider currentCourse, + TimeProvider timeProvider, + ILogger logger) + { + this.tokens = tokens; + this.courses = courses; + this.grades = grades; + this.currentCourse = currentCourse; + this.timeProvider = timeProvider; + this.logger = logger; + } + + [HttpPost] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task Post(CancellationToken cancellationToken) + { + var token = Request.Headers["X-Ahk-Token"].FirstOrDefault(); + var receivedSignature = Request.Headers["X-Ahk-Sha256"].FirstOrDefault(); + var deliveryId = Request.Headers["X-Ahk-Delivery"].FirstOrDefault(); + var dateStr = Request.Headers[HeaderNames.Date].FirstOrDefault(); + + logger.LogInformation( + "evaluation-result request with X-Ahk-Delivery='{DeliveryId}', X-Ahk-Token = '{Token}'", deliveryId, token); + + // Order and wording of these checks are the ported contract; the evaluator's logs are full of them. + if (string.IsNullOrEmpty(dateStr)) + return BadRequest(new { error = "Date header missing" }); + + if (!DateTime.TryParseExact( + dateStr, + "R", + CultureInfo.InvariantCulture, + DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal, + out var date)) + { + return BadRequest(new { error = "Date header value not valid RFC1123 string" }); + } + + var now = timeProvider.GetUtcNow().UtcDateTime; + if (date < now.Add(-MaxClockSkew) || date > now.Add(MaxClockSkew)) + return BadRequest(new { error = "Date header value is not close enough to current date" }); + + if (string.IsNullOrEmpty(receivedSignature)) + return BadRequest(new { error = "X-Ahk-Sha256 header missing" }); + + if (string.IsNullOrEmpty(token)) + return BadRequest(new { error = "X-Ahk-Token header missing" }); + + var secret = await tokens.GetSecretForTokenAsync(token, cancellationToken); + if (string.IsNullOrEmpty(secret)) + return BadRequest(new { error = "X-Ahk-Token invalid" }); + + var requestBody = await RawBody.ReadAsync(Request, cancellationToken); + var signedUrl = Request.GetDisplayUrl(); + + if (!HmacSha256Validator.IsSignatureValid(Request.Method, signedUrl, date, requestBody, receivedSignature, secret)) + { + // The URL is the usual culprit and the only part of the signed string that is safe to log — never + // the body (student code) and never the secret. + logger.LogDebug( + "evaluation-result signature mismatch for X-Ahk-Delivery='{DeliveryId}'; signed URL was '{Url}'", deliveryId, signedUrl); + return BadRequest(new { error = "X-Ahk-Sha256 signature not valid" }); + } + + if (!TryReadPayload(requestBody, out var payload, out var deserializationError)) + return BadRequest(new { error = deserializationError }); + + // New in the portal: one deployment serves every course, so the course comes from the token — the + // authenticated credential — rather than from the caller-supplied repository name. + var course = await courses.ResolveByWebhookTokenAsync(token, cancellationToken); + if (course is null) + { + // Same message as an unknown token: a caller must not be able to tell a revoked token from one + // whose course was deleted. + logger.LogWarning("evaluation-result token '{Token}' resolved to no course", token); + return BadRequest(new { error = "X-Ahk-Token invalid" }); + } + + var repositoryCourse = await courses.ResolveByRepositoryAsync(payload.GitHubRepoName, cancellationToken); + if (repositoryCourse is not null && repositoryCourse.Id != course.Id) + { + // Not fatal — the token is authoritative — but it means a course is using another course's token, + // and the grade is about to land in the wrong place. + logger.LogWarning( + "evaluation-result for '{Repository}' resolves to course '{RepositoryCourse}' but its token belongs to '{TokenCourse}'", + payload.GitHubRepoName, repositoryCourse.Slug, course.Slug); + } + + currentCourse.Set(course.Id); + + logger.LogInformation( + "evaluation-result request with X-Ahk-Delivery='{DeliveryId}' accepted, starting processing", deliveryId); + + try + { + await grades.RecordEvaluationResultAsync(course.Id, ToInput(payload), date, cancellationToken); + logger.LogInformation("evaluation-result request handled with success for X-Ahk-Delivery='{DeliveryId}'", deliveryId); + return Ok(); + } +#pragma warning disable CA1031 // Ported shape: the caller gets the failure text, because it is a build log. + catch (Exception ex) +#pragma warning restore CA1031 + { + logger.LogError(ex, "evaluation-result webhook failed for X-Ahk-Delivery='{DeliveryId}'", deliveryId); + return StatusCode(StatusCodes.Status500InternalServerError, new { error = ex.ToString() }); + } + } + + private static EvaluationResultInput ToInput(EvaluationResultRequest payload) + => new() + { + NeptunCode = payload.NeptunCode, + GitHubRepoName = payload.GitHubRepoName, + GitHubBranch = payload.GitHubBranch, + GitHubCommitHash = payload.GitHubCommitHash, + GitHubPullRequestNum = payload.GitHubPullRequestNum, + Origin = payload.Origin, + Result = payload.Result?.Select(r => new EvaluationTaskResult + { + ExerciseName = r.ExerciseName, + TaskName = r.TaskName, + Points = r.Points, + Comment = r.Comment, + }).ToList() ?? new List(), + }; + + /// Port of grade-management's PayloadReader, error string included. + private static bool TryReadPayload(string requestBody, out EvaluationResultRequest payload, out string error) + { + payload = null!; + error = null!; + + try + { + var result = JsonSerializer.Deserialize(requestBody, PayloadOptions); + if (result is null) + { + error = "Body cannot be deserialized as JSON: the body was null"; + return false; + } + + var validationResults = new List(); + if (!Validator.TryValidateObject(result, new ValidationContext(result, null, null), validationResults, validateAllProperties: true)) + { + error = $"Body cannot be deserialized as JSON: {string.Join(", ", validationResults.Select(s => s.ErrorMessage).ToArray())}"; + return false; + } + + payload = result; + return true; + } + catch (JsonException ex) + { + error = $"Body cannot be deserialized as JSON: {ex.Message}"; + return false; + } + } +} diff --git a/ahk-backend/Ahk.Web.Server/Program.cs b/ahk-backend/Ahk.Web.Server/Program.cs index 9f1ac92f..1b1a773b 100644 --- a/ahk-backend/Ahk.Web.Server/Program.cs +++ b/ahk-backend/Ahk.Web.Server/Program.cs @@ -15,6 +15,7 @@ using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; namespace Ahk.Web.Server; @@ -213,6 +214,11 @@ private static void ConfigureServices(WebApplicationBuilder builder) // ---- Domain services (Ahk.Web.Services) ---- builder.Services.AddMemoryCache(); + + // The CI callback rejects a request whose Date header has drifted more than ten minutes, so it needs a + // clock a test can move. TimeProvider is the framework's answer to grade-management's IDateTimeProvider. + builder.Services.TryAddSingleton(TimeProvider.System); + builder.Services.AddAhkServices(); // ---- MVC + OpenAPI (NSwag document consumed by the Angular code generator) ---- diff --git a/ahk-backend/Ahk.Web.Services/Integrations/HmacSha256Validator.cs b/ahk-backend/Ahk.Web.Services/Integrations/HmacSha256Validator.cs new file mode 100644 index 00000000..a3376500 --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/Integrations/HmacSha256Validator.cs @@ -0,0 +1,56 @@ +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.Security.Cryptography; +using System.Text; + +namespace Ahk.Web.Services.Integrations; + +/// +/// Verifies the signature the evaluator container puts on an evaluation result. Ported verbatim from +/// grade-management/.../Helpers/HmacSha256Validator.cs; the counterpart that produces these signatures +/// is Go, in publish-results-pr/internal/publishtoapi, and the two are pinned to each other by an +/// identical set of golden vectors in both test suites. +/// +/// The string to sign is four parts joined by single \n characters, with no trailing newline: +/// UPPERCASE(verb), lowercase(url), the RFC1123 date, then the raw body. Two details are +/// load-bearing and must not be "modernised": the key is ASCII bytes (matching Go's +/// []byte(secret) for the ASCII-only secrets the generator produces), and the whole URL including +/// any query string is signed — which is why the callback URL has to match byte for byte on both +/// sides. +/// +public static class HmacSha256Validator +{ + public static bool IsSignatureValid(string httpVerb, string httpUrl, DateTime date, string requestBody, string? receivedSignature, string? secret) + { + if (string.IsNullOrEmpty(receivedSignature) || string.IsNullOrEmpty(secret)) + return false; + + var key = Encoding.ASCII.GetBytes(secret); + var payloadSignedBytes = GetBytesToSign(httpVerb, httpUrl, date, requestBody); + + using var hmac = new HMACSHA256(key); + var hash = hmac.ComputeHash(payloadSignedBytes); + var expectedSignature = Convert.ToBase64String(hash); + + // Compare length first, do not even try to compare content if these do not match. + if (receivedSignature.Length != expectedSignature.Length) + return false; + + return receivedSignature.Equals(expectedSignature, StringComparison.Ordinal); + } + + /// The signed string, exposed so a failing request can be diagnosed without leaking the secret. + [SuppressMessage("Globalization", "CA1308:Normalize strings to uppercase", Justification = "URL normalized to lowercase by design; the Go client does the same.")] + public static string GetStringToSign(string httpVerb, string httpUrl, DateTime date, string requestBody) + => string.Concat( + httpVerb.ToUpperInvariant(), + "\n", + httpUrl.ToLowerInvariant(), + "\n", + date.ToString("R", CultureInfo.InvariantCulture), + "\n", + requestBody); + + private static byte[] GetBytesToSign(string httpVerb, string httpUrl, DateTime date, string requestBody) + => new UTF8Encoding(encoderShouldEmitUTF8Identifier: false).GetBytes(GetStringToSign(httpVerb, httpUrl, date, requestBody)); +} From 4f4bfb97255eb51ed9219d8602391f03ae71356c Mon Sep 17 00:00:00 2001 From: Bence Kovari Date: Sun, 9 Aug 2026 01:55:52 +0200 Subject: [PATCH 13/19] test(portal): cover the ported webhook receiver and CI callback 201 tests pass, up from 81. Also hardens two things the port inherited. Parity suites, ported case-for-case from the Azure Functions so the portal provably accepts what they accepted: the ahk-monitor.yml grammar, the /ahk ok grammar (including that the last matching line wins - the parse loop's missing break is behaviour, not a bug), and the X-Hub-Signature-256 vectors. HmacSha256ValidatorTests carries the three golden vectors that exist identically in grade-management's suite AND in publish-results-pr's Go tests. Reproducing those base64 strings is the proof the portal is wire-compatible with evaluator containers already running in student repositories, which cannot be redeployed on our schedule. WebhookHandlerRegistrationTests turns the delivery-id invariant into a build failure: GitHubDeliveryId is globally unique but a delivery fans out to several handlers, so at most one handler per event may write a status event. Break that and rows vanish into the redelivery guard - in production, silently. Endpoint tests pin the full response contract of both routes, including that neither returns 401 (proving [AllowAnonymous] works because Program.cs has no fallback policy), and that a body signed with another course's secret is indistinguishable from any other bad signature - which is what contains the parse-before-verify ordering. Two security fixes from review of the previous commits, neither changing which requests are accepted: - Both validators compared signatures with string.Equals, which returns at the first differing character and lets a forged signature be refined a character at a time by timing. Now CryptographicOperations.FixedTimeEquals. - The CI callback logged the caller's token in full at Information level, as grade-management did, putting working credentials into shipped logs. Now masked to a last-four hint, matching the admin API's convention. Octokit models in tests are built by deserializing the JSON GitHub would send rather than through their constructors, which are long and mostly irrelevant. Co-Authored-By: Claude Opus 5 --- .../Ahk.Web.Server.Tests.csproj | 1 + .../EvaluationResultEndpointTests.cs | 297 +++++++++++++++++ .../GitHubWebhookEndpointTests.cs | 299 ++++++++++++++++++ .../GitHubWebhooks/ParserParityTests.cs | 108 +++++++ .../GitHubWebhooks/SignatureParityTests.cs | 100 ++++++ .../WebhookHandlerRegistrationTests.cs | 113 +++++++ .../GitHubWebhooks/WebhookStatusEventTests.cs | 299 ++++++++++++++++++ .../EvaluationResultController.cs | 13 +- .../GitHubSignatureValidator.cs | 9 +- .../Integrations/HmacSha256Validator.cs | 9 +- .../Ahk.Web.Services/SignatureComparison.cs | 30 ++ 11 files changed, 1266 insertions(+), 12 deletions(-) create mode 100644 ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/EvaluationResultEndpointTests.cs create mode 100644 ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/GitHubWebhookEndpointTests.cs create mode 100644 ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/ParserParityTests.cs create mode 100644 ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/SignatureParityTests.cs create mode 100644 ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/WebhookHandlerRegistrationTests.cs create mode 100644 ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/WebhookStatusEventTests.cs create mode 100644 ahk-backend/Ahk.Web.Services/SignatureComparison.cs diff --git a/ahk-backend/Ahk.Web.Server.Tests/Ahk.Web.Server.Tests.csproj b/ahk-backend/Ahk.Web.Server.Tests/Ahk.Web.Server.Tests.csproj index 4e3a9e19..86dd719d 100644 --- a/ahk-backend/Ahk.Web.Server.Tests/Ahk.Web.Server.Tests.csproj +++ b/ahk-backend/Ahk.Web.Server.Tests/Ahk.Web.Server.Tests.csproj @@ -11,6 +11,7 @@ + diff --git a/ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/EvaluationResultEndpointTests.cs b/ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/EvaluationResultEndpointTests.cs new file mode 100644 index 00000000..46ff35e5 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/EvaluationResultEndpointTests.cs @@ -0,0 +1,297 @@ +using System.Globalization; +using System.Net; +using System.Security.Cryptography; +using System.Text; +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Ahk.Web.Services.Grading; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Time.Testing; +using Xunit; + +namespace Ahk.Web.Server.Tests.GitHubWebhooks; + +/// +/// The CI callback, end to end. The client on the other side of this contract is a Go binary already running +/// inside student repositories that are updated on their own schedule, so both the accepted request and every +/// rejection message are fixed by compatibility rather than by taste. +/// +public class EvaluationResultEndpointTests : IClassFixture +{ + private const string Url = "/api/integrations/evaluation-result"; + private const string Token = "ci-token-value"; + private const string Secret = "ci-secret-value"; + private const string RevokedToken = "revoked-token-value"; + + /// Exactly what publish-results-pr emits, imageFiles included. + private const string SampleBody = + """{"gitHubRepoName":"bmeaut/viaubc01-abc123","gitHubBranch":"refs/pull/12/merge","gitHubPullRequestNum":12,"gitHubCommitHash":"aa11cc33","neptunCode":"abc123","imageFiles":[],"result":[{"exerciseName":"ex1","taskName":"t1","points":2,"comment":"ok"},{"exerciseName":"ex1","taskName":"t2","points":3},{"exerciseName":"ex2","taskName":"t3","points":1}],"origin":"https://github.com/bmeaut/viaubc01-abc123/commit/aa11cc33"}"""; + + private readonly CallbackAppFactory factory; + + public EvaluationResultEndpointTests(CallbackAppFactory factory) => this.factory = factory; + + [Fact] + public async Task ValidRequest_RecordsAnUnconfirmedGrade() + { + var response = await PostAsync(SampleBody); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + using var scope = factory.Services.CreateScope(); + var db = scope.ServiceProvider.GetRequiredService(); + + var grade = await db.GradeRecords.IgnoreQueryFilters() + .Include(g => g.Points) + .Include(g => g.Submission) + .OrderByDescending(g => g.Id) + .FirstAsync(); + + Assert.False(grade.Confirmed); + Assert.Equal(GradeService.AutomatedActor, grade.Actor); + Assert.Equal("ABC123", grade.Neptun); + Assert.Equal(12, grade.PrNumber); + Assert.Equal("bmeaut/viaubc01-abc123", grade.Submission!.GitHubRepoName); + + // The Date header is the grade's timestamp, not the moment the server happened to handle it. + Assert.Equal(factory.Now.UtcDateTime, grade.Date.UtcDateTime, TimeSpan.FromSeconds(1)); + + // Per-task detail is discarded; points are summed per exercise and ordered by name. + Assert.Equal(new[] { ("ex1", 5d), ("ex2", 1d) }, grade.Points.OrderBy(p => p.Order).Select(p => (p.Name, p.Point))); + } + + /// + /// The Go client sends imageFiles, which has never had a counterpart here. Tolerating unknown + /// members is a compatibility requirement, not laxness — a strict deserializer would fail every student + /// build at once. + /// + [Fact] + public async Task UnknownMembersAreIgnored() + { + var body = """{"gitHubRepoName":"bmeaut/viaubc01-xyz999","neptunCode":"xyz999","imageFiles":["a.png"],"somethingBrandNew":{"nested":true},"result":[]}"""; + + var response = await PostAsync(body); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + } + + [Fact] + public async Task MissingDateHeader_Returns400() => + await AssertBadRequestAsync(await PostAsync(SampleBody, date: null), "Date header missing"); + + [Fact] + public async Task UnparseableDateHeader_Returns400() => + await AssertBadRequestAsync(await PostAsync(SampleBody, date: "notadate"), "Date header value not valid RFC1123 string"); + + [Theory] + [InlineData(-25)] + [InlineData(11)] + public async Task DateOutsideSkewWindow_Returns400(int minutes) + { + var skewed = factory.Now.AddMinutes(minutes).UtcDateTime.ToString("R", CultureInfo.InvariantCulture); + + await AssertBadRequestAsync( + await PostAsync(SampleBody, date: skewed), "Date header value is not close enough to current date"); + } + + /// Ten minutes either way is inside the window; the boundary is where clock drift actually lives. + [Theory] + [InlineData(-9)] + [InlineData(9)] + public async Task DateInsideSkewWindow_IsAccepted(int minutes) + { + var skewed = factory.Now.AddMinutes(minutes).UtcDateTime; + var response = await PostAsync(SampleBody, date: skewed.ToString("R", CultureInfo.InvariantCulture)); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + } + + [Fact] + public async Task MissingSignatureHeader_Returns400() => + await AssertBadRequestAsync(await PostAsync(SampleBody, signature: null), "X-Ahk-Sha256 header missing"); + + [Fact] + public async Task MissingTokenHeader_Returns400() => + await AssertBadRequestAsync(await PostAsync(SampleBody, token: null), "X-Ahk-Token header missing"); + + [Fact] + public async Task UnknownToken_Returns400() => + await AssertBadRequestAsync(await PostAsync(SampleBody, token: "no-such-token"), "X-Ahk-Token invalid"); + + /// + /// Revoking must take effect immediately. The secret lookup is cached for an hour, so this is really a test + /// that revocation evicts the cache rather than waiting it out. + /// + [Fact] + public async Task RevokedToken_Returns400() => + await AssertBadRequestAsync(await PostAsync(SampleBody, token: RevokedToken), "X-Ahk-Token invalid"); + + [Fact] + public async Task WrongSignature_Returns400() => + await AssertBadRequestAsync(await PostAsync(SampleBody, signature: "notavalidsignature="), "X-Ahk-Sha256 signature not valid"); + + /// + /// The signature covers the URL, so a request signed for a different address must fail. This is the + /// failure mode behind a misconfigured AHK_APPURL, and the reason the documented value is byte-exact. + /// + [Fact] + public async Task SignatureOverADifferentUrl_Returns400() + { + var date = factory.Now.UtcDateTime; + var wrongUrlSignature = Sign("POST", "https://ahk.aut.bme.hu/api/evaluation-result", date, SampleBody, Secret); + + await AssertBadRequestAsync(await PostAsync(SampleBody, signature: wrongUrlSignature), "X-Ahk-Sha256 signature not valid"); + } + + [Fact] + public async Task BodyThatIsNotJson_Returns400() => + await AssertBadRequestAsync(await PostAsync("notjson"), "Body cannot be deserialized as JSON"); + + /// The two top-level fields the legacy DTO actually enforced. + [Theory] + [InlineData("""{"neptunCode":"abc123","result":[]}""")] + [InlineData("""{"gitHubRepoName":"bmeaut/viaubc01-abc123","result":[]}""")] + public async Task BodyMissingRequiredFields_Returns400(string body) => + await AssertBadRequestAsync(await PostAsync(body), "Body cannot be deserialized as JSON"); + + /// Authentication here is the signature alone; a 401 would mean a fallback policy had crept in. + [Fact] + public async Task WithoutCredentials_IsNotUnauthorized() + { + var client = factory.CreateClient(); + using var content = new StringContent(SampleBody, Encoding.UTF8, "application/json"); + + var response = await client.PostAsync(Url, content); + + Assert.NotEqual(HttpStatusCode.Unauthorized, response.StatusCode); + Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + } + + private static async Task AssertBadRequestAsync(HttpResponseMessage response, string expectedError) + { + Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + Assert.Contains(expectedError, await response.Content.ReadAsStringAsync(), StringComparison.Ordinal); + } + + /// + /// Reimplements the Go client's scheme rather than calling the validator, so these tests cannot pass by + /// agreeing with a mistake in the code under test. + /// + private static string Sign(string verb, string url, DateTime date, string body, string secret) + { + var stringToSign = string.Concat( + verb.ToUpperInvariant(), + "\n", + url.ToLowerInvariant(), + "\n", + date.ToString("R", CultureInfo.InvariantCulture), + "\n", + body); + + using var hmac = new HMACSHA256(Encoding.ASCII.GetBytes(secret)); + return Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign))); + } + + private async Task PostAsync( + string body, string? token = Token, string? signature = "", string? date = "") + { + var client = factory.CreateClient(); + + // TestServer serves over http; UseHttpsRedirection no-ops without a configured https port, which is + // what the existing smoke tests already rely on. + var absoluteUrl = new Uri(client.BaseAddress!, Url).ToString(); + var dateValue = date is null ? null : (date.Length == 0 ? factory.Now.UtcDateTime.ToString("R", CultureInfo.InvariantCulture) : date); + + using var request = new HttpRequestMessage(HttpMethod.Post, Url) + { + Content = new StringContent(body, Encoding.UTF8, "application/json"), + }; + + if (token is not null) + request.Headers.Add("X-Ahk-Token", token); + + // Without validation: HttpClient parses Date itself and refuses to send a malformed one, which would + // make the "not valid RFC1123" branch unreachable from a test. Over the wire nothing stops a caller + // (or a proxy) from sending exactly that. + if (dateValue is not null) + request.Headers.TryAddWithoutValidation("Date", dateValue); + + if (signature is not null) + { + // When the date is missing or malformed the request is rejected before the signature is ever + // checked, so signing over the frozen clock keeps the helper total. + var signedDate = dateValue is not null + && DateTime.TryParseExact(dateValue, "R", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal, out var parsed) + ? parsed + : factory.Now.UtcDateTime; + + request.Headers.Add("X-Ahk-Sha256", signature.Length == 0 ? Sign("POST", absoluteUrl, signedDate, body, Secret) : signature); + } + + request.Headers.Add("X-Ahk-Delivery", "delivery-1"); + + return await client.SendAsync(request); + } + + public sealed class CallbackAppFactory : WebApplicationFactory + { + /// Frozen, so the ten-minute skew window can be tested from both sides. + public DateTimeOffset Now { get; } = new(2026, 8, 9, 12, 0, 0, TimeSpan.Zero); + + protected override IHost CreateHost(IHostBuilder builder) + { + builder.UseEnvironment("Testing"); + builder.ConfigureServices(services => + { + var toRemove = services.Where(d => + d.ServiceType == typeof(DbContextOptions) || + d.ServiceType == typeof(DbContextOptions) || + d.ServiceType == typeof(ApplicationDbContext) || + d.ServiceType == typeof(TimeProvider) || + (d.ServiceType.IsGenericType && d.ServiceType.Name.StartsWith("IDbContextOptionsConfiguration", StringComparison.Ordinal))) + .ToList(); + foreach (var descriptor in toRemove) + services.Remove(descriptor); + + services.AddDbContext(options => options.UseInMemoryDatabase("EvaluationResultEndpointTests")); + services.AddSingleton(new FakeTimeProvider(Now)); + }); + + var host = base.CreateHost(builder); + + using (var scope = host.Services.CreateScope()) + { + var db = scope.ServiceProvider.GetRequiredService(); + if (!db.Courses.IgnoreQueryFilters().Any()) + { + var course = new Course + { + Slug = "viaubc01", + Name = "Sample Course", + GitHubOrganization = "bmeaut", + RepoNamePrefix = "viaubc01", + }; + db.Courses.Add(course); + db.SaveChanges(); + + db.CourseWebhookTokens.AddRange( + new CourseWebhookToken { CourseId = course.Id, Token = Token, Secret = Secret, Description = "active" }, + new CourseWebhookToken + { + CourseId = course.Id, + Token = RevokedToken, + Secret = Secret, + Description = "revoked", + RevokedAt = DateTimeOffset.UtcNow, + }); + db.SaveChanges(); + } + } + + return host; + } + } +} diff --git a/ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/GitHubWebhookEndpointTests.cs b/ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/GitHubWebhookEndpointTests.cs new file mode 100644 index 00000000..0d4a79b2 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/GitHubWebhookEndpointTests.cs @@ -0,0 +1,299 @@ +using System.Globalization; +using System.Net; +using System.Security.Cryptography; +using System.Text; +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Ahk.Web.Services.GitHub; +using Ahk.Web.Services.GitHubWebhooks; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Moq; +using Octokit; +using Xunit; + +namespace Ahk.Web.Server.Tests.GitHubWebhooks; + +/// +/// The webhook endpoint's response contract, end to end through the real pipeline. +/// +/// Every status here is read by a human in the GitHub App's Advanced → Recent Deliveries tab, so each +/// one is part of the diagnostic surface rather than an implementation detail — which is why they are pinned +/// individually, error strings included. +/// +public class GitHubWebhookEndpointTests : IClassFixture +{ + private const string Secret = "dev-webhook-secret"; + private const string Url = "/api/integrations/github"; + + private readonly WebhookAppFactory factory; + + public GitHubWebhookEndpointTests(WebhookAppFactory factory) => this.factory = factory; + + [Fact] + public async Task MissingEventHeader_Returns400() + { + var response = await PostAsync(Body("bmeaut/viaubc01-abc123"), eventName: null); + + Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + Assert.Contains("X-GitHub-Event header missing", await response.Content.ReadAsStringAsync(), StringComparison.Ordinal); + } + + [Fact] + public async Task MissingSignatureHeader_Returns400() + { + var response = await PostAsync(Body("bmeaut/viaubc01-abc123"), signature: null); + + Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + Assert.Contains("X-Hub-Signature-256 header missing", await response.Content.ReadAsStringAsync(), StringComparison.Ordinal); + } + + /// The pre-parse must reject anything it cannot route, without ever throwing on hostile input. + [Theory] + [InlineData("not json at all")] + [InlineData("{}")] + [InlineData("{\"repository\":null}")] + [InlineData("{\"repository\":{}}")] + [InlineData("[]")] + public async Task BodyWithoutRepositoryName_Returns400(string body) + { + var response = await PostAsync(body); + + Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + Assert.Contains("no repository information in webhook payload", await response.Content.ReadAsStringAsync(), StringComparison.Ordinal); + } + + /// + /// 202, not 4xx. An organization contains repositories that are not a course, and a delivery log full of + /// red teaches administrators to ignore it. + /// + [Fact] + public async Task RepositoryInNoCourse_Returns202() + { + var response = await PostAsync(Body("someoneelse/unrelated-repo")); + + Assert.Equal(HttpStatusCode.Accepted, response.StatusCode); + Assert.Contains("not mapped to a course", await response.Content.ReadAsStringAsync(), StringComparison.Ordinal); + } + + [Fact] + public async Task CourseWithIntegrationTurnedOff_Returns202() + { + var response = await PostAsync(Body("bmeaut/paused-abc123")); + + Assert.Equal(HttpStatusCode.Accepted, response.StatusCode); + Assert.Contains("turned off", await response.Content.ReadAsStringAsync(), StringComparison.Ordinal); + } + + /// + /// A course with no secret is a misconfiguration an administrator has to fix, not a delivery to shrug off — + /// so it keeps the legacy 500 rather than joining the 202 cases. + /// + [Fact] + public async Task CourseWithoutWebhookSecret_Returns500() + { + var response = await PostAsync(Body("bmeaut/nosecret-abc123")); + + Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode); + Assert.Contains("GitHub secret not configured", await response.Content.ReadAsStringAsync(), StringComparison.Ordinal); + } + + [Fact] + public async Task WrongSignature_Returns400() + { + var response = await PostAsync(Body("bmeaut/viaubc01-abc123"), signature: "sha256=deadbeef"); + + Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + Assert.Contains("Payload signature not valid", await response.Content.ReadAsStringAsync(), StringComparison.Ordinal); + } + + /// + /// A body signed with a *different* course's secret must be indistinguishable from any other bad + /// signature. This is what contains the parse-before-verify ordering: guessing a repository name buys an + /// attacker nothing. + /// + [Fact] + public async Task BodySignedWithAnotherCoursesSecret_Returns400() + { + var body = Body("bmeaut/viaubc01-abc123"); + var response = await PostAsync(body, signature: Sign(body, "a-different-courses-secret")); + + Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + Assert.Contains("Payload signature not valid", await response.Content.ReadAsStringAsync(), StringComparison.Ordinal); + } + + /// A correctly signed delivery for an event nobody handles is a 200 that says so. + [Fact] + public async Task ValidDeliveryForUnhandledEvent_Returns200WithResult() + { + var response = await PostAsync(Body("bmeaut/viaubc01-abc123"), eventName: "ping"); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Contains("Event ping is not of interest", await response.Content.ReadAsStringAsync(), StringComparison.Ordinal); + } + + /// + /// The dispatcher must receive the resolved course and the per-course run threshold — the two things the + /// port had to add, and the two a handler cannot obtain for itself. + /// + [Fact] + public async Task ValidDelivery_PassesCourseAndThresholdToDispatcher() + { + factory.Dispatcher.Reset(); + + var response = await PostAsync(Body("bmeaut/viaubc01-abc123"), eventName: "pull_request", deliveryId: "delivery-42"); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + var context = Assert.Single(factory.Dispatcher.Seen); + Assert.Equal("pull_request", context.GitHubEventName); + Assert.Equal("delivery-42", context.DeliveryId); + Assert.Equal(7, context.WorkflowRunThreshold); + Assert.NotEqual(0, context.CourseId); + } + + /// + /// The endpoint is anonymous by design — the HMAC is the authentication. A 401 here would mean a fallback + /// authorization policy had crept into Program.cs and silently broken every delivery. + /// + [Fact] + public async Task WithoutCredentials_IsNotUnauthorized() + { + var response = await PostAsync("not json at all"); + + Assert.NotEqual(HttpStatusCode.Unauthorized, response.StatusCode); + Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); + } + + private static string Body(string repositoryFullName) + => $"{{\"repository\":{{\"full_name\":\"{repositoryFullName}\"}}}}"; + + /// + /// Signs the way GitHub does, implemented here rather than reused from the validator so the endpoint tests + /// do not merely agree with the code they are testing. + /// + private static string Sign(string body, string secret) + { + using var hmac = new HMACSHA256(Encoding.ASCII.GetBytes(secret)); + var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(body)); + return "sha256=" + Convert.ToHexString(hash).ToLower(CultureInfo.InvariantCulture); + } + + private async Task PostAsync( + string body, string? eventName = "push", string? signature = "", string? deliveryId = "delivery-1") + { + var client = factory.CreateClient(); + + using var request = new HttpRequestMessage(HttpMethod.Post, Url) + { + Content = new StringContent(body, Encoding.UTF8, "application/json"), + }; + + if (eventName is not null) + request.Headers.Add("X-GitHub-Event", eventName); + + if (deliveryId is not null) + request.Headers.Add("X-GitHub-Delivery", deliveryId); + + // The empty-string default means "sign it correctly"; null means "omit the header entirely". + if (signature is not null) + request.Headers.Add("X-Hub-Signature-256", signature.Length == 0 ? Sign(body, Secret) : signature); + + return await client.SendAsync(request); + } + + /// Records what the endpoint handed it, so the handlers themselves stay out of these tests. + public sealed class RecordingDispatcher : IGitHubWebhookDispatcher + { + public List Seen { get; } = new(); + + public void Reset() => Seen.Clear(); + + public Task ProcessAsync(GitHubWebhookContext context, WebhookResult result, CancellationToken cancellationToken = default) + { + Seen.Add(context); + result.LogInfo($"Event {context.GitHubEventName} is not of interest"); + return Task.CompletedTask; + } + } + + public sealed class WebhookAppFactory : WebApplicationFactory + { + public RecordingDispatcher Dispatcher { get; } = new(); + + protected override IHost CreateHost(IHostBuilder builder) + { + builder.UseEnvironment("Testing"); + builder.ConfigureServices(services => + { + var toRemove = services.Where(d => + d.ServiceType == typeof(DbContextOptions) || + d.ServiceType == typeof(DbContextOptions) || + d.ServiceType == typeof(ApplicationDbContext) || + d.ServiceType == typeof(IGitHubWebhookDispatcher) || + d.ServiceType == typeof(ICourseGitHubAppTokenProvider) || + d.ServiceType == typeof(ICourseGitHubClientFactory) || + (d.ServiceType.IsGenericType && d.ServiceType.Name.StartsWith("IDbContextOptionsConfiguration", StringComparison.Ordinal))) + .ToList(); + foreach (var descriptor in toRemove) + services.Remove(descriptor); + + services.AddDbContext(options => options.UseInMemoryDatabase("GitHubWebhookEndpointTests")); + services.AddSingleton(Dispatcher); + + // Nothing may reach api.github.com from a test. + var tokenProvider = new Mock(); + tokenProvider + .Setup(p => p.GetForCourseAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync(new GitHubInstallationToken("installation-token", 1, new Dictionary(), "all")); + services.AddSingleton(tokenProvider.Object); + + var clientFactory = new Mock(); + clientFactory.Setup(f => f.CreateForToken(It.IsAny())).Returns(Mock.Of()); + services.AddSingleton(clientFactory.Object); + }); + + var host = base.CreateHost(builder); + + using (var scope = host.Services.CreateScope()) + { + var db = scope.ServiceProvider.GetRequiredService(); + if (!db.Courses.IgnoreQueryFilters().Any()) + { + // Three courses in one organization, so repo-prefix resolution is exercised rather than + // assumed, and each of the configuration failure modes has somewhere to happen. + db.Courses.AddRange( + new Course + { + Slug = "viaubc01", + Name = "Healthy course", + GitHubOrganization = "bmeaut", + RepoNamePrefix = "viaubc01", + GitHubConfig = new CourseGitHubConfig { GitHubWebhookSecret = Secret, WorkflowRunThreshold = 7, Enabled = true }, + }, + new Course + { + Slug = "paused", + Name = "Integration turned off", + GitHubOrganization = "bmeaut", + RepoNamePrefix = "paused", + GitHubConfig = new CourseGitHubConfig { GitHubWebhookSecret = Secret, Enabled = false }, + }, + new Course + { + Slug = "nosecret", + Name = "No webhook secret stored", + GitHubOrganization = "bmeaut", + RepoNamePrefix = "nosecret", + GitHubConfig = new CourseGitHubConfig { GitHubWebhookSecret = null, Enabled = true }, + }); + db.SaveChanges(); + } + } + + return host; + } + } +} diff --git a/ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/ParserParityTests.cs b/ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/ParserParityTests.cs new file mode 100644 index 00000000..79665da6 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/ParserParityTests.cs @@ -0,0 +1,108 @@ +using Ahk.Web.Services.GitHubWebhooks; +using Xunit; + +namespace Ahk.Web.Server.Tests.GitHubWebhooks; + +/// +/// The .github/ahk-monitor.yml opt-in gate. Cases ported verbatim from +/// github-monitor/.../UnitTests/ConfigYamlParserTest.cs — existing course templates carry these exact +/// spellings, so the accepted set is a compatibility contract, not a style choice. +/// +public class ConfigYamlParserTests +{ + [Theory] + [InlineData("enabled")] + [InlineData("enabled: true")] + [InlineData("enabled: yes")] + [InlineData("enabled: 1")] + [InlineData("enabled: true\r")] + [InlineData("enabled: true\n")] + [InlineData("enabled: true\r\n")] + [InlineData("enabled: true\r\naaa: 1")] + [InlineData("aaa: 1\r\nenabled: true")] + public void ConfigYamlIsEnabled(string value) => Assert.True(ConfigYamlParser.IsEnabled(value)); + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("aaa")] + [InlineData("enabl")] + [InlineData("enabled: false")] + [InlineData("enabled: no")] + [InlineData("enabled: 0")] + [InlineData("enabled: maybe")] + [InlineData("enabled hello")] + public void ConfigYamlIsDisabled(string? value) => Assert.False(ConfigYamlParser.IsEnabled(value)); +} + +/// +/// The /ahk ok chatops grammar. Cases ported verbatim from +/// github-monitor/.../UnitTests/GradeCommentParserTest.cs: teachers have this syntax in their fingers +/// and any narrowing of it silently stops grading a pull request. +/// +public class GradeCommentParserTests +{ + [Theory] + [InlineData("/ahk ok")] + [InlineData("/ahk ok hello")] + [InlineData("/ahk ok 1")] + [InlineData("/ahk ok 1,2")] + [InlineData("/ahk ok 1, 2")] + [InlineData("/ahk ok 1, 2.5")] + [InlineData("/ahk ok 1.33, 2.5, 44")] + [InlineData("/ahk ok 1.33;2.5;44")] + [InlineData("/ahk ok 1,33 2,5 44")] + [InlineData("something\r\n\r\n/ahk ok")] + [InlineData("something\r\n\r\n/ahk ok 1.33, 2.5, 44")] + [InlineData("/ahk ok\r\n\r\nsomething")] + [InlineData("/ahk ok 1.33, 2.5, 44\r\n\r\nsomething")] + [InlineData("/AHK OK 5")] + public void IsGradeComment(string value) => Assert.True(new GradeCommentParser(value).IsMatch); + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("aaa")] + [InlineData("@ok")] + [InlineData("/ahkok")] + [InlineData("/ahk okk")] + [InlineData("ahk ok")] + [InlineData("something\r\n\r\n/ahkok")] + [InlineData("something\r\n\r\n/ahk okk")] + [InlineData("ahk ok\r\n\r\nsomething")] + public void IsNotGradeComment(string? value) => Assert.False(new GradeCommentParser(value).IsMatch); + + [Theory] + [InlineData("/ahk ok", new double[0])] + [InlineData("/ahk ok hello", new double[0])] + [InlineData("/ahk ok 1", new[] { 1d })] + [InlineData("/ahk ok 1,2", new[] { 1.2 })] + [InlineData("/ahk ok 1, 2", new[] { 1d, 2d })] + [InlineData("/ahk ok 1,2 2", new[] { 1.2, 2d })] + [InlineData("/ahk ok 1, 2.5", new[] { 1d, 2.5 })] + [InlineData("/ahk ok 1.33, 2.5, 44", new[] { 1.33, 2.5, 44d })] + [InlineData("/ahk ok 1.33;2.5;44", new[] { 1.33, 2.5, 44d })] + [InlineData("/ahk ok 1,33 2,5 44", new[] { 1.33, 2.5, 44d })] + [InlineData("something\r\n\r\n/ahk ok 1, 2.5", new[] { 1d, 2.5 })] + [InlineData("/ahk ok 1.33, 2.5, 44\r\n\r\nsomething", new[] { 1.33, 2.5, 44d })] + public void GradesAreParsed(string value, double[] expectedGrades) + { + var parsed = new GradeCommentParser(value); + + Assert.Equal(expectedGrades.Length > 0, parsed.HasGrades); + Assert.Equal(expectedGrades, parsed.Grades); + } + + /// + /// The parse loop deliberately does not stop at the first match, so a comment that corrects itself grades + /// with the correction. Looks like a bug, is behaviour — pinned so nobody "fixes" it. + /// + [Fact] + public void LastMatchingLineWins() + { + var parsed = new GradeCommentParser("/ahk ok 1 2\r\nsorry, I meant:\r\n/ahk ok 3 4"); + + Assert.True(parsed.IsMatch); + Assert.Equal(new[] { 3d, 4d }, parsed.Grades); + } +} diff --git a/ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/SignatureParityTests.cs b/ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/SignatureParityTests.cs new file mode 100644 index 00000000..646556d6 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/SignatureParityTests.cs @@ -0,0 +1,100 @@ +using Ahk.Web.Services.GitHubWebhooks; +using Ahk.Web.Services.Integrations; +using Xunit; + +namespace Ahk.Web.Server.Tests.GitHubWebhooks; + +/// +/// GitHub's X-Hub-Signature-256 scheme. Vectors ported verbatim from +/// github-monitor/.../UnitTests/GitHubSignatureValidatorTest.cs: reproducing them is what proves the +/// portal accepts exactly the deliveries the Azure Function did. +/// +public class GitHubSignatureValidatorTests +{ + private const string Secret = "Wcks02cnncc67c33"; + + [Theory] + [InlineData("aaaaaa\r\nbbbbbbb\r\ncccccccccc\r\n", "sha256=3926a12bd47c5e3fe91cb2e6dd0c605438ac469c4de09e560b97029a3f751a88")] + [InlineData("qqqq\r\nsdfsdfsdfsdf\r\nwwwwwwwwwwwww\r\n", "sha256=0d5a916d47e3a2d6ebaa1ca9fafb425e122f892edb8464496a2c8107169ba828")] + [InlineData("aaaaaaqqqqqqqqqqqqqqq", "sha256=9abd46d0b161c9b171c36c6e2b88fd27d498ee08555cb4f34d39ddb2467273fe")] + public void SignatureIsValid(string payload, string expectedSignature) + => Assert.True(GitHubSignatureValidator.IsSignatureValid(payload, expectedSignature, Secret)); + + [Theory] + [InlineData("aaaaaa\r\nbbbbbbb\r\ncccccccccc\r\n", "sha1=dummy")] + [InlineData("aaaaaa\r\nbbbbbbb\r\ncccccccccc\r\n", "sha1=aaaaaaaa")] + [InlineData("aaaaaa\r\nbbbbbbb\r\ncccccccccc\r\n", "dummy")] + [InlineData("aaaaaa\r\nbbbbbbb\r\ncccccccccc\r\n", "")] + [InlineData("aaaaaa\r\nbbbbbbb\r\ncccccccccc\r\n", null)] + public void SignatureIsNotValid(string payload, string? receivedSignature) + => Assert.False(GitHubSignatureValidator.IsSignatureValid(payload, receivedSignature, Secret)); + + /// A course with no secret stored must never accidentally validate. + [Fact] + public void MissingSecretNeverValidates() + => Assert.False(GitHubSignatureValidator.IsSignatureValid( + "aaaaaa", "sha256=3926a12bd47c5e3fe91cb2e6dd0c605438ac469c4de09e560b97029a3f751a88", secret: null)); +} + +/// +/// The CI callback's HMAC scheme. +/// +/// These three vectors exist identically in both +/// grade-management/Ahk.GradeManagement.Tests/UnitTests/HmacSha256ValidatorTest.cs and the Go client's +/// publish-results-pr/internal/publishtoapi/hmacsignature_test.go. Reproducing them here is the proof +/// that the portal is wire-compatible with the evaluator container already running in student repositories — +/// which cannot be redeployed on our schedule. +/// +public class HmacSha256ValidatorTests +{ + private const string Secret = "Wcks02cnncc67c33"; + private const string HttpVerb = "POST"; + private const string HttpUrl = "https://my.url.com/address"; + + private static readonly DateTime Date = new(2021, 9, 1, 13, 34, 56, DateTimeKind.Utc); + + [Theory] + [InlineData("aaaaaa\r\nbbbbbbb\r\ncccccccccc\r\n", "SGAhL9hfzLqi30G1uqtQyErRC4oKBlxT9NImaJ/V9CQ=")] + [InlineData("qqqq\r\nsdfsdfsdfsdf\r\nwwwwwwwwwwwww\r\n", "K7lZXguubpUONKhHh40lAzxt2vPyZnm6LkjLhrYPwAo=")] + [InlineData("aaaaaaqqqqqqqqqqqqqqq", "cN9KEIb9uO7VskC9mmZ7wWkzqOXirFXcjqB3i4cK0mA=")] + public void SignatureIsValid(string payload, string expectedSignature) + => Assert.True(HmacSha256Validator.IsSignatureValid(HttpVerb, HttpUrl, Date, payload, expectedSignature, Secret)); + + [Fact] + public void SignatureIsNotValidWhenVerbDiffers() + => Assert.False(HmacSha256Validator.IsSignatureValid( + "PUT", HttpUrl, Date, "aaaaaaqqqqqqqqqqqqqqq", "cN9KEIb9uO7VskC9mmZ7wWkzqOXirFXcjqB3i4cK0mA=", Secret)); + + [Fact] + public void SignatureIsNotValidWhenUrlDiffers() + => Assert.False(HmacSha256Validator.IsSignatureValid( + HttpVerb, "https://my.url.com/other", Date, "aaaaaaqqqqqqqqqqqqqqq", "cN9KEIb9uO7VskC9mmZ7wWkzqOXirFXcjqB3i4cK0mA=", Secret)); + + [Fact] + public void SignatureIsNotValidWhenDateDiffers() + => Assert.False(HmacSha256Validator.IsSignatureValid( + HttpVerb, HttpUrl, Date.AddSeconds(1), "aaaaaaqqqqqqqqqqqqqqq", "cN9KEIb9uO7VskC9mmZ7wWkzqOXirFXcjqB3i4cK0mA=", Secret)); + + [Fact] + public void SignatureIsNotValidWhenPayloadDiffers() + => Assert.False(HmacSha256Validator.IsSignatureValid( + HttpVerb, HttpUrl, Date, "aaaaaaqqqqqqqqqqqqqqqa", "cN9KEIb9uO7VskC9mmZ7wWkzqOXirFXcjqB3i4cK0mA=", Secret)); + + /// + /// Both sides lower-case the URL before signing, so a differently cased AHK_APPURL still verifies. + /// The only forgiving part of an otherwise byte-exact contract, and worth knowing when diagnosing one. + /// + [Fact] + public void UrlCasingDoesNotMatter() + => Assert.True(HmacSha256Validator.IsSignatureValid( + HttpVerb, "https://MY.URL.com/Address", Date, "aaaaaaqqqqqqqqqqqqqqq", "cN9KEIb9uO7VskC9mmZ7wWkzqOXirFXcjqB3i4cK0mA=", Secret)); + + /// Four parts, single LF separators, no trailing newline. + [Fact] + public void StringToSignHasTheDocumentedShape() + { + var stringToSign = HmacSha256Validator.GetStringToSign("post", "HTTPS://My.Url.Com/Address", Date, "body"); + + Assert.Equal("POST\nhttps://my.url.com/address\nWed, 01 Sep 2021 13:34:56 GMT\nbody", stringToSign); + } +} diff --git a/ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/WebhookHandlerRegistrationTests.cs b/ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/WebhookHandlerRegistrationTests.cs new file mode 100644 index 00000000..3eb4ab5e --- /dev/null +++ b/ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/WebhookHandlerRegistrationTests.cs @@ -0,0 +1,113 @@ +using Ahk.Web.Services; +using Ahk.Web.Services.GitHubWebhooks; +using Ahk.Web.Services.GitHubWebhooks.Handlers; +using Ahk.Web.Services.GitHubWebhooks.Handlers.GradeComment; +using Ahk.Web.Services.GitHubWebhooks.Handlers.StatusTracking; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.DependencyInjection; +using Moq; +using Xunit; + +namespace Ahk.Web.Server.Tests.GitHubWebhooks; + +/// +/// Guards the shape of the handler set itself, without running a delivery. +/// +public class WebhookHandlerRegistrationTests +{ + /// + /// ⚠️ The invariant behind SubmissionEvent.GitHubDeliveryId. + /// + /// The column is globally unique so a redelivered webhook does not duplicate rows, but one delivery fans + /// out to several handlers. That only works while at most one handler per event name writes a + /// status event. Add a second writer for an existing event and its rows silently vanish (the + /// redelivery guard swallows them) or the unique index rejects them on SQL Server — either way, in + /// production, not here. So the invariant is a failing build instead. + /// + /// If you genuinely need two writers for one event, key the delivery id per handler first. + /// + [Fact] + public void AtMostOneStatusEventWriterPerEvent() + { + var offenders = ResolveHandlers() + .Where(h => h is IStatusEventWriter) + .GroupBy(h => h.GitHubEventName, StringComparer.OrdinalIgnoreCase) + .Where(g => g.Count() > 1) + .Select(g => $"{g.Key}: {string.Join(", ", g.Select(h => h.GetType().Name))}") + .ToList(); + + Assert.True( + offenders.Count == 0, + $"More than one handler writes a status event for the same GitHub event, which breaks the delivery-id " + + $"redelivery guard: {string.Join("; ", offenders)}"); + } + + /// + /// The exact handler set ported from github-monitor. Pinned so that dropping a registration — which costs + /// nothing at compile time and shows up only as a rule that quietly stopped being enforced — fails here. + /// + [Fact] + public void AllPortedHandlersAreRegistered() + { + var registered = ResolveHandlers() + .Select(h => (h.GetType(), h.GitHubEventName)) + .ToHashSet(); + + var expected = new HashSet<(Type, string)> + { + (typeof(BranchProtectionRuleHandler), "create"), + (typeof(IssueCommentEditDeleteHandler), "issue_comment"), + (typeof(PullRequestOpenDuplicateHandler), "pull_request"), + (typeof(PullRequestReviewToAssigneeHandler), "pull_request"), + (typeof(GradeCommandIssueCommentHandler), "issue_comment"), + (typeof(GradeCommandReviewCommentHandler), "pull_request_review"), + (typeof(ActionWorkflowRunHandler), "workflow_run"), + (typeof(BranchCreateStatusTrackingHandler), "create"), + (typeof(WorkflowRunStatusTrackingHandler), "workflow_run"), + (typeof(PullRequestStatusTrackingHandler), "pull_request"), + }; + + Assert.Equal(expected, registered); + } + + /// + /// Handlers post comments, and the order they appear in under a pull request is the order they are + /// registered in. DI returns an IEnumerable<T> in registration order, which is the whole + /// reason github-monitor's explicit dispatch-config builder was not needed in the port — so that property + /// is worth a test of its own. + /// + [Fact] + public void RegistrationOrderMatchesTheOriginal() + { + var pullRequestHandlers = ResolveHandlers() + .Where(h => h.GitHubEventName == "pull_request") + .Select(h => h.GetType()) + .ToList(); + + Assert.Equal( + new[] + { + typeof(PullRequestOpenDuplicateHandler), + typeof(PullRequestReviewToAssigneeHandler), + typeof(PullRequestStatusTrackingHandler), + }, + pullRequestHandlers); + } + + /// + /// Resolves the handlers alone, with their collaborators stubbed. Registering the whole service graph would + /// drag in the DbContext and the HTTP clients for a question that is purely about registration. + /// + private static IReadOnlyList ResolveHandlers() + { + var services = new ServiceCollection(); + services.AddLogging(); + services.AddSingleton(new MemoryCache(new MemoryCacheOptions())); + services.AddSingleton(Mock.Of()); + services.AddSingleton(Mock.Of()); + services.AddAhkGitHubWebhooks(); + + var provider = services.BuildServiceProvider(); + return provider.GetServices().ToList(); + } +} diff --git a/ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/WebhookStatusEventTests.cs b/ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/WebhookStatusEventTests.cs new file mode 100644 index 00000000..bb8c8105 --- /dev/null +++ b/ahk-backend/Ahk.Web.Server.Tests/GitHubWebhooks/WebhookStatusEventTests.cs @@ -0,0 +1,299 @@ +using Ahk.Web.Data; +using Ahk.Web.Data.Entities; +using Ahk.Web.Services.GitHubWebhooks; +using Ahk.Web.Services.GitHubWebhooks.Handlers.StatusTracking; +using Ahk.Web.Services.StatusTracking; +using Ahk.Web.Services.Submissions; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging.Abstractions; +using Moq; +using Octokit; +using Octokit.Internal; +using Xunit; + +namespace Ahk.Web.Server.Tests.GitHubWebhooks; + +/// +/// The status-tracking handlers, run against a real on EF InMemory. +/// +/// These handlers are the whole of the dashboard's data: what a teacher sees is a projection over the rows +/// written here, so the mapping from GitHub payload to event subtype is worth pinning field by field. +/// +public class WebhookStatusEventTests +{ + private const int CourseId = 1; + private const string Repository = "bmeaut/viaubc01-abc123"; + + /// Creation of the *default* branch is how a new repository is recognised. + [Fact] + public async Task DefaultBranchCreate_RecordsRepositoryCreated() + { + using var db = NewContext(nameof(DefaultBranchCreate_RecordsRepositoryCreated)); + var handler = NewBranchHandler(db); + + var result = await handler.ExecuteAsync(NewContextFor(CreateBranchPayload("main"), "delivery-1")); + + Assert.Contains("repository create lifecycle handled", result.Result, StringComparison.Ordinal); + var recorded = Assert.Single(await ReadEventsAsync(db)); + Assert.IsType(recorded); + Assert.Equal("delivery-1", recorded.GitHubDeliveryId); + } + + [Fact] + public async Task NonDefaultBranchCreate_RecordsBranchCreated() + { + using var db = NewContext(nameof(NonDefaultBranchCreate_RecordsBranchCreated)); + var handler = NewBranchHandler(db); + + var result = await handler.ExecuteAsync(NewContextFor(CreateBranchPayload("feature/homework"), "delivery-1")); + + Assert.Contains("branch create lifecycle handled", result.Result, StringComparison.Ordinal); + var recorded = Assert.Single(await ReadEventsAsync(db)); + Assert.Equal("feature/homework", Assert.IsType(recorded).Branch); + } + + /// A tag is not a branch. + [Fact] + public async Task TagCreate_RecordsNothing() + { + using var db = NewContext(nameof(TagCreate_RecordsNothing)); + var handler = NewBranchHandler(db); + + var result = await handler.ExecuteAsync(NewContextFor(CreateBranchPayload("v1.0", refType: "tag"), "delivery-1")); + + Assert.Contains("not of interest", result.Result, StringComparison.Ordinal); + Assert.Empty(await ReadEventsAsync(db)); + } + + [Fact] + public async Task PullRequestOpened_RecordsPullRequestEventAndLinksTheStudent() + { + using var db = NewContext(nameof(PullRequestOpened_RecordsPullRequestEventAndLinksTheStudent)); + var handler = new PullRequestStatusTrackingHandler(NewEventService(db), NewCache(), NullLogger.Instance); + + var result = await handler.ExecuteAsync(NewContextFor(PullRequestPayload("opened"), "delivery-1")); + + Assert.Contains("pull request lifecycle handled", result.Result, StringComparison.Ordinal); + + var recorded = Assert.IsType(Assert.Single(await ReadEventsAsync(db))); + Assert.Equal(12, recorded.Number); + Assert.Equal("opened", recorded.Action); + Assert.Equal("https://github.com/bmeaut/viaubc01-abc123/pull/12", recorded.HtmlUrl); + Assert.Equal("ABC123", recorded.Neptun); + Assert.Equal(new[] { "teacher1" }, recorded.Assignees); + + // neptun.txt is what ties a repository to a person; a pull request is usually where it first appears. + var submission = await db.Submissions.IgnoreQueryFilters().Include(s => s.Student).SingleAsync(); + Assert.Equal("ABC123", submission.Student!.Neptun); + } + + [Fact] + public async Task PullRequestSynchronize_IsNotOfInterest() + { + using var db = NewContext(nameof(PullRequestSynchronize_IsNotOfInterest)); + var handler = new PullRequestStatusTrackingHandler(NewEventService(db), NewCache(), NullLogger.Instance); + + var result = await handler.ExecuteAsync(NewContextFor(PullRequestPayload("synchronize"), "delivery-1")); + + Assert.Contains("not of interest", result.Result, StringComparison.Ordinal); + Assert.Empty(await ReadEventsAsync(db)); + } + + [Fact] + public async Task CompletedWorkflowRun_RecordsItsConclusion() + { + using var db = NewContext(nameof(CompletedWorkflowRun_RecordsItsConclusion)); + var handler = new WorkflowRunStatusTrackingHandler(NewEventService(db), NewCache(), NullLogger.Instance); + + var result = await handler.ExecuteAsync(NewContextFor(WorkflowRunPayload("completed", "failure"), "delivery-1")); + + Assert.Contains("workflow_run lifecycle handled", result.Result, StringComparison.Ordinal); + Assert.Equal("failure", Assert.IsType(Assert.Single(await ReadEventsAsync(db))).Conclusion); + } + + /// + /// GitHub redelivers, and an administrator can redeliver by hand from the Advanced tab. The delivery id + /// makes that idempotent. + /// + /// Note this exercises 's own explicit guard rather than the + /// database: EF InMemory does not enforce the filtered unique index that backs it in production. + /// + [Fact] + public async Task RedeliveringTheSameDelivery_RecordsOneRow() + { + using var db = NewContext(nameof(RedeliveringTheSameDelivery_RecordsOneRow)); + var handler = NewBranchHandler(db); + + var first = await handler.ExecuteAsync(NewContextFor(CreateBranchPayload("feature/homework"), "delivery-1")); + var second = await handler.ExecuteAsync(NewContextFor(CreateBranchPayload("feature/homework"), "delivery-1")); + + Assert.Contains("action performed", first.Result, StringComparison.Ordinal); + Assert.Contains("redelivery, event already recorded", second.Result, StringComparison.Ordinal); + Assert.Single(await ReadEventsAsync(db)); + } + + /// Two genuine deliveries are two events, redelivery guard notwithstanding. + [Fact] + public async Task DistinctDeliveries_RecordBothRows() + { + using var db = NewContext(nameof(DistinctDeliveries_RecordBothRows)); + var handler = NewBranchHandler(db); + + await handler.ExecuteAsync(NewContextFor(CreateBranchPayload("feature/a"), "delivery-1")); + await handler.ExecuteAsync(NewContextFor(CreateBranchPayload("feature/b"), "delivery-2")); + + Assert.Equal(2, (await ReadEventsAsync(db)).Count); + } + + /// + /// The opt-in gate. A repository without .github/ahk-monitor.yml is ignored entirely — no event, no + /// rule enforced — which is the single most common reason a correctly wired webhook appears to do nothing. + /// + [Fact] + public async Task RepositoryWithoutAhkMonitorYml_IsIgnored() + { + using var db = NewContext(nameof(RepositoryWithoutAhkMonitorYml_IsIgnored)); + var handler = NewBranchHandler(db); + + var result = await handler.ExecuteAsync(NewContextFor(CreateBranchPayload("main"), "delivery-1", monitorYml: null)); + + Assert.Contains("no ahk-monitor.yml or disabled", result.Result, StringComparison.Ordinal); + Assert.Empty(await ReadEventsAsync(db)); + } + + [Fact] + public async Task RepositoryWithDisabledAhkMonitorYml_IsIgnored() + { + using var db = NewContext(nameof(RepositoryWithDisabledAhkMonitorYml_IsIgnored)); + var handler = NewBranchHandler(db); + + var result = await handler.ExecuteAsync(NewContextFor(CreateBranchPayload("main"), "delivery-1", monitorYml: "enabled: false")); + + Assert.Contains("no ahk-monitor.yml or disabled", result.Result, StringComparison.Ordinal); + Assert.Empty(await ReadEventsAsync(db)); + } + + [Fact] + public async Task GarbagePayload_IsReportedNotThrown() + { + using var db = NewContext(nameof(GarbagePayload_IsReportedNotThrown)); + var handler = NewBranchHandler(db); + + var result = await handler.ExecuteAsync(NewContextFor("{\"nonsense\":1}", "delivery-1")); + + Assert.Contains("payload error", result.Result, StringComparison.Ordinal); + Assert.Empty(await ReadEventsAsync(db)); + } + + private static BranchCreateStatusTrackingHandler NewBranchHandler(ApplicationDbContext db) + => new(NewEventService(db), NewCache(), NullLogger.Instance); + + private static ISubmissionEventService NewEventService(ApplicationDbContext db) + => new SubmissionEventService(db, new SubmissionResolver(db)); + + private static IMemoryCache NewCache() => new MemoryCache(new MemoryCacheOptions()); + + private static async Task> ReadEventsAsync(ApplicationDbContext db) + => await db.SubmissionEvents.IgnoreQueryFilters().ToListAsync(); + + private static ApplicationDbContext NewContext(string name) + { + var options = new DbContextOptionsBuilder().UseInMemoryDatabase(name).Options; + var db = new ApplicationDbContext(options, new FixedCourseProvider()); + + db.Courses.Add(new Course { Id = CourseId, Slug = "viaubc01", Name = "Sample Course", GitHubOrganization = "bmeaut" }); + db.SaveChanges(); + + return db; + } + + private static GitHubWebhookContext NewContextFor(string body, string deliveryId, string? monitorYml = "enabled: true") + => new() + { + CourseId = CourseId, + GitHubEventName = "create", + DeliveryId = deliveryId, + RequestBody = body, + GitHubClient = NewGitHubClient(monitorYml), + WorkflowRunThreshold = 5, + }; + + /// + /// Only the two file reads the handlers make are stubbed. Octokit models are built by deserializing the + /// JSON GitHub would send rather than through their constructors, which are long and mostly irrelevant. + /// + private static IGitHubClient NewGitHubClient(string? monitorYml) + { + var contents = new Mock(); + + contents + .Setup(c => c.GetAllContentsByRef(It.IsAny(), ".github/ahk-monitor.yml", It.IsAny())) + .Returns(() => monitorYml is null + ? throw new NotFoundException("not found", System.Net.HttpStatusCode.NotFound) + : Task.FromResult>(new[] { FileContent(monitorYml) })); + + contents + .Setup(c => c.GetAllContentsByRef(It.IsAny(), "neptun.txt", It.IsAny())) + .ReturnsAsync(new[] { FileContent("ABC123\n") }); + + var repositories = new Mock(); + repositories.SetupGet(r => r.Content).Returns(contents.Object); + + var client = new Mock(); + client.SetupGet(c => c.Repository).Returns(repositories.Object); + + return client.Object; + } + + private static RepositoryContent FileContent(string text) + { + var encoded = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(text)); + return new SimpleJsonSerializer().Deserialize( + $$"""{"name":"f","path":"f","sha":"s","size":{{text.Length}},"type":"file","encoding":"base64","content":"{{encoded}}"}"""); + } + + private static string CreateBranchPayload(string branch, string refType = "branch") + => $$""" + { + "ref": "{{branch}}", + "ref_type": "{{refType}}", + "repository": { "id": 55, "name": "viaubc01-abc123", "full_name": "{{Repository}}", "default_branch": "main", + "owner": { "login": "bmeaut", "id": 9, "type": "Organization" } }, + "installation": { "id": 123 } + } + """; + + private static string PullRequestPayload(string action) + => $$""" + { + "action": "{{action}}", + "number": 12, + "pull_request": { + "number": 12, + "html_url": "https://github.com/bmeaut/viaubc01-abc123/pull/12", + "head": { "ref": "feature/homework" }, + "assignees": [ { "login": "teacher1", "id": 3 } ] + }, + "repository": { "id": 55, "name": "viaubc01-abc123", "full_name": "{{Repository}}", "default_branch": "main", + "owner": { "login": "bmeaut", "id": 9, "type": "Organization" } }, + "installation": { "id": 123 } + } + """; + + private static string WorkflowRunPayload(string action, string conclusion) + => $$""" + { + "action": "{{action}}", + "workflow_run": { "conclusion": "{{conclusion}}" }, + "repository": { "id": 55, "name": "viaubc01-abc123", "full_name": "{{Repository}}", "default_branch": "main", + "owner": { "login": "bmeaut", "id": 9, "type": "Organization" } }, + "installation": { "id": 123 } + } + """; + + private sealed class FixedCourseProvider : ICurrentCourseProvider + { + public int? CurrentCourseId => CourseId; + } +} diff --git a/ahk-backend/Ahk.Web.Server/Integrations/EvaluationResultController.cs b/ahk-backend/Ahk.Web.Server/Integrations/EvaluationResultController.cs index d01bd715..37a7d0ca 100644 --- a/ahk-backend/Ahk.Web.Server/Integrations/EvaluationResultController.cs +++ b/ahk-backend/Ahk.Web.Server/Integrations/EvaluationResultController.cs @@ -73,7 +73,7 @@ public async Task Post(CancellationToken cancellationToken) var dateStr = Request.Headers[HeaderNames.Date].FirstOrDefault(); logger.LogInformation( - "evaluation-result request with X-Ahk-Delivery='{DeliveryId}', X-Ahk-Token = '{Token}'", deliveryId, token); + "evaluation-result request with X-Ahk-Delivery='{DeliveryId}', X-Ahk-Token = '{Token}'", deliveryId, MaskToken(token)); // Order and wording of these checks are the ported contract; the evaluator's logs are full of them. if (string.IsNullOrEmpty(dateStr)) @@ -125,7 +125,7 @@ public async Task Post(CancellationToken cancellationToken) { // Same message as an unknown token: a caller must not be able to tell a revoked token from one // whose course was deleted. - logger.LogWarning("evaluation-result token '{Token}' resolved to no course", token); + logger.LogWarning("evaluation-result token '{Token}' resolved to no course", MaskToken(token)); return BadRequest(new { error = "X-Ahk-Token invalid" }); } @@ -159,6 +159,15 @@ public async Task Post(CancellationToken cancellationToken) } } + /// + /// A token is a live credential: it selects a course and is half of the pair that authenticates a grade + /// write. grade-management logged it whole, which put working credentials into any log the application + /// ships to. Only enough is kept to tell two tokens apart while diagnosing — the same last-four convention + /// the admin API uses when it reports a stored secret. + /// + private static string MaskToken(string? token) + => string.IsNullOrEmpty(token) ? "(none)" : $"…{token[^Math.Min(4, token.Length)..]}"; + private static EvaluationResultInput ToInput(EvaluationResultRequest payload) => new() { diff --git a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/GitHubSignatureValidator.cs b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/GitHubSignatureValidator.cs index 3905ccc3..10affba5 100644 --- a/ahk-backend/Ahk.Web.Services/GitHubWebhooks/GitHubSignatureValidator.cs +++ b/ahk-backend/Ahk.Web.Services/GitHubWebhooks/GitHubSignatureValidator.cs @@ -23,11 +23,10 @@ public static bool IsSignatureValid(string requestBody, string? receivedSignatur var hash = hmac.ComputeHash(requestBytes); var expectedSignature = "sha256=" + ToHexString(hash); - // Compare length first, do not even try to compare content if these do not match. - if (receivedSignature.Length != expectedSignature.Length) - return false; - - return receivedSignature.Equals(expectedSignature, StringComparison.Ordinal); + // Constant-time: github-monitor used string.Equals here, which returns at the first differing + // character and lets a forged signature be refined one character at a time by timing. See + // SignatureComparison. + return SignatureComparison.FixedTimeEquals(receivedSignature, expectedSignature); } private static string ToHexString(byte[] bytes) diff --git a/ahk-backend/Ahk.Web.Services/Integrations/HmacSha256Validator.cs b/ahk-backend/Ahk.Web.Services/Integrations/HmacSha256Validator.cs index a3376500..1f7dc09d 100644 --- a/ahk-backend/Ahk.Web.Services/Integrations/HmacSha256Validator.cs +++ b/ahk-backend/Ahk.Web.Services/Integrations/HmacSha256Validator.cs @@ -32,11 +32,10 @@ public static bool IsSignatureValid(string httpVerb, string httpUrl, DateTime da var hash = hmac.ComputeHash(payloadSignedBytes); var expectedSignature = Convert.ToBase64String(hash); - // Compare length first, do not even try to compare content if these do not match. - if (receivedSignature.Length != expectedSignature.Length) - return false; - - return receivedSignature.Equals(expectedSignature, StringComparison.Ordinal); + // Constant-time: grade-management used string.Equals here, which returns at the first differing + // character and lets a forged signature be refined one character at a time by timing. See + // SignatureComparison. + return SignatureComparison.FixedTimeEquals(receivedSignature, expectedSignature); } /// The signed string, exposed so a failing request can be diagnosed without leaking the secret. diff --git a/ahk-backend/Ahk.Web.Services/SignatureComparison.cs b/ahk-backend/Ahk.Web.Services/SignatureComparison.cs new file mode 100644 index 00000000..bad8d02d --- /dev/null +++ b/ahk-backend/Ahk.Web.Services/SignatureComparison.cs @@ -0,0 +1,30 @@ +using System.Runtime.InteropServices; +using System.Security.Cryptography; + +namespace Ahk.Web.Services; + +/// +/// Compares two signature strings without leaking, through how long the comparison took, how much of a guess +/// was correct. +/// +/// Both webhook schemes in this application originally compared their signatures with +/// string.Equals, which returns at the first differing character. That is the textbook setup for a +/// remote timing attack: an attacker who can measure response times refines a forged signature one character +/// at a time, turning an infeasible search into a linear one. Neither validator's accept/reject behaviour +/// changes by fixing it — only the timing does. +/// +/// The length check is deliberately left fast and early. Signature length is fixed by the algorithm and +/// public knowledge, so it is not a secret to leak. +/// +internal static class SignatureComparison +{ + public static bool FixedTimeEquals(string received, string expected) + { + if (received.Length != expected.Length) + return false; + + return CryptographicOperations.FixedTimeEquals( + MemoryMarshal.AsBytes(received.AsSpan()), + MemoryMarshal.AsBytes(expected.AsSpan())); + } +} From db19ce405d6ad6b105b120115019b097cc50f8e3 Mon Sep 17 00:00:00 2001 From: Bence Kovari Date: Sun, 9 Aug 2026 02:00:02 +0200 Subject: [PATCH 14/19] docs: the portal now hosts every entry point github-app.md was actively misleading: it told administrators to point the App's webhook at github-monitor because the portal's receiver did not exist. That instruction is what produced the 405s this work started from. It now documents the real URL, that the webhook secret is per course, the five subscribed events, and a per-course cutover checklist. New: a "Delivery responses" table explaining what each status means when read in Advanced -> Recent Deliveries, since that page is the only diagnostic surface GitHub offers. Troubleshooting gains the three symptoms actually hit while debugging - 405 with Allow: GET, HEAD (URL points at the SPA fallback), 200 with nothing happening (repo not opted in), and no deliveries at all (installation limited to selected repositories). New docs/ci-callback.md covers the HMAC contract end to end. It leads with the fact that the URL is signed, because that is the failure mode operators will actually meet, and http:// fails via a 307 and then a scheme mismatch - which looks nothing like a URL problem. The permissions table no longer marks half the grants "github-monitor only"; the portal needs them now. Contents moves to read/write - it reads ahk-monitor.yml and neptun.txt out of every student repository. CLAUDE.md records the non-obvious constraints a future change could quietly break: the one-status-event-per-delivery invariant, why course resolution has to precede signature validation and what must stay out of that stretch, the 12-hour ahk-monitor.yml cache, the GetForCourseAsync(Course) null trap, and that a GitHub App has one webhook URL so cutover is a flip rather than a parallel run. Co-Authored-By: Claude Opus 5 --- .claude/settings.json | 4 +- CLAUDE.md | 12 ++- README.md | 8 +- ahk-backend/README.md | 43 +++++++++-- ahk-backend/docs/ci-callback.md | 133 ++++++++++++++++++++++++++++++++ ahk-backend/docs/github-app.md | 100 ++++++++++++++++++++---- 6 files changed, 270 insertions(+), 30 deletions(-) create mode 100644 ahk-backend/docs/ci-callback.md diff --git a/.claude/settings.json b/.claude/settings.json index a763c6cd..f1cd7915 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -101,7 +101,9 @@ "PowerShell(try { Get-NetTCPConnection -LocalPort 7443 -State Listen -ErrorAction Stop | Select-Object -ExpandProperty OwningProcess -Unique | ForEach-Object { Stop-Process -Id $_ -Force -ErrorAction SilentlyContinue } } catch {}; Write-Output \"backend stopped\")", "Bash(node shot4.mjs)", "Bash(wsl.exe bash *)", - "Bash(node shot5.mjs)" + "Bash(node shot5.mjs)", + "Bash(git add *)", + "Bash(git commit *)" ], "additionalDirectories": [ "\\tmp", diff --git a/CLAUDE.md b/CLAUDE.md index 465221d5..ee7e7d1d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,7 +8,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co The repo is a monorepo of independent applications, each in its own top-level directory with its own solution/module, README, and CI workflows. There is no root-level build — each app builds separately. -It is mid-transition: the **four original apps** (`github-monitor`, `grade-management`, `review-ui`, `publish-results-pr`) are the production system today, and a **new centralized portal** (`ahk-backend` + `ahk-frontend`) is being built to replace the per-course Azure deployments with a single multi-course site at `ahk.aut.bme.hu`. The portal now has auth (local + BME OIDC), the full course-scoped **data model**, the domain **services**, the read endpoints (`grades`, `statuses`, CSV export), the **site administration surface** (course CRUD, per-course GitHub integration, CI callback tokens, staff, users/roles, health checks) with its Angular console, and a one-time Cosmos→MSSQL importer. Still **not** ported: the write-side entry points — the GitHub webhook receiver, `/ahk ok` chatops, and the HMAC-verified CI callback. When working in this repo, be clear which of the two systems a task targets. +It is mid-transition: the **four original apps** (`github-monitor`, `grade-management`, `review-ui`, `publish-results-pr`) are the production system today, and a **new centralized portal** (`ahk-backend` + `ahk-frontend`) is being built to replace the per-course Azure deployments with a single multi-course site at `ahk.aut.bme.hu`. The portal now has auth (local + BME OIDC), the full course-scoped **data model**, the domain **services**, the read endpoints (`grades`, `statuses`, CSV export), the **site administration surface** (course CRUD, per-course GitHub integration, CI callback tokens, staff, users/roles, health checks) with its Angular console, and a one-time Cosmos→MSSQL importer. The write-side entry points are now ported too — the **GitHub webhook receiver**, **`/ahk ok` chatops** and the **HMAC-verified CI callback** — so the portal is feature-complete and a course can run on it with no Azure Functions. The four apps stay deployed for courses that have not migrated; **a GitHub App has one webhook URL, so per course the switch is a flip, not a parallel run** (cutover checklist in `ahk-backend/docs/github-app.md`). When working in this repo, be clear which of the two systems a task targets. ## The four applications and how they connect @@ -46,6 +46,7 @@ Replaces the per-course Azure Function deployments with one site whose domain da - **ahk-backend** — ASP.NET Core **.NET 10** (`Ahk.Web.slnx`). Layering: `Ahk.Web.Server` (controllers/middleware/auth, thin) → `Ahk.Web.Services` (domain logic) → `Ahk.Web.Data` (EF Core + **MSSQL**, Identity, migrations, seeder, `Normalize`). `Ahk.Web.Import` is a **throwaway** Cosmos-JSON→MSSQL console importer that references Data directly and **bypasses Services** (bulk movement, not domain ops). Tests in `Ahk.Web.Server.Tests` (xUnit + Moq). - **No repository layer** — `DbContext` is already Unit of Work + repository. The legacy Cosmos repositories exist only because Cosmos has no composable LINQ context; that reason is gone. - **ahk-frontend** — **Angular 21** SPA (standalone components + signals). API clients/DTOs under `src/app/api/` are **NSwag-generated** from the backend's OpenAPI doc — never hand-edit them. +- **Octokit is the portal's single GitHub API client**, built by `ICourseGitHubClientFactory` (`Ahk.Web.Services/GitHub/`). One exception: `CourseGitHubAppTokenProvider` stays on the named `"github"` `HttpClient` because it is the auth bootstrap (hand-rolled RS256 App JWT → installation token), not an API call, and moving it would change the permissions shape `GitHubAppInstallationHealthCheck` reads. `IGitHubRepositoryService`'s interface and its four record projections are deliberately Octokit-free — that is what lets `AssignmentInviteTests` mock it strictly. Design decisions (rationale in the architecture plan and `ahk-backend/README.md`): - **Auth**: cookie-based ASP.NET Identity (returns 401/403, never redirects) + an **OIDC** external provider (config `Authentication:Oidc:*`; disabled when empty). Deliberately **not** `MapIdentityApi` (no OIDC support, bearer-token focus, fixed shapes). @@ -59,13 +60,18 @@ Design decisions (rationale in the architecture plan and `ahk-backend/README.md` - **eduID identifies a user by Neptun code, not email/username.** `ApplicationUser.NeptunCode` is filtered-unique (blank stored as null, may repeat; any value unique). First OIDC login matches an existing account by Neptun and links the external login, so an admin-pre-created account is never duplicated (`ExternalAuthController`). Admin create/update enforce the same rule (blank→null, else `Normalize.Neptun`, 400 on clash). eduID **always refreshes email**; the claim sync never writes username. - The client secret is never in config — `dotnet user-secrets` locally, `Authentication__Oidc__ClientSecret` in production. - **Dev mock OIDC provider** (`Ahk.Web.Server/MockOidc/`): only the production redirect URI is registered with BME, so localhost cannot use the real IdP. Enabled by `Authentication:Oidc:UseMockProvider` in Development; serves discovery/authorize/token/userinfo/JWKS at `/mock-oidc` and issues **genuinely signed** RS256 id_tokens so the real validation path runs. Switch persona with `GET /mock-oidc/persona?user=instructor|student|noclaims`. -- **Course scoping**: path segment `/api/{course}/...`; `CourseResolutionMiddleware` resolves the `Course` and an `ICurrentCourseProvider` drives an EF Core global query filter over `ICourseScoped` entities; the `CourseMember` authorization policy gates access. Host/admin routes live under `/api/admin/...`. Machine-to-machine endpoints (webhooks / CI callbacks, added during the port) will resolve their course from the payload/token, **not** the path segment. +- **Course scoping**: path segment `/api/{course}/...`; `CourseResolutionMiddleware` resolves the `Course` and an `ICurrentCourseProvider` drives an EF Core global query filter over `ICourseScoped` entities; the `CourseMember` authorization policy gates access. Host/admin routes live under `/api/admin/...`. Machine-to-machine endpoints have **no** `{course}` segment and resolve their course from the payload/token instead: `POST /api/integrations/github` (from `repository.full_name`, via `ICourseResolutionService.ResolveByRepositoryAsync`) and `POST /api/integrations/evaluation-result` (from the `X-Ahk-Token` header). Both are `[AllowAnonymous]` — a signature is the authentication, and `Program.cs` deliberately has no `FallbackPolicy` — and both are `[ApiExplorerSettings(IgnoreApi = true)]` so NSwag emits no client for them. - **Site admins can open any course.** `CourseMembershipAuthorizationHandler` grants `CourseMember` to the `Admin` role, so `GET /api/auth/me` lists *every* course for an admin (flagged `viaSiteAdmin` where there is no membership row). The SPA's switcher and `courseGuard` read that one list and need no admin special case — keep it that way rather than branching on `isAdmin()` in new screens. - **Admin API credential rule**: stored secrets are never returned (only `has*` flags plus a last-four hint). On update, each credential field means: `null` = leave alone, `""` = clear, anything else = replace. That is what makes saving an untouched form safe. -- **Course health checks** (`Ahk.Web.Services/Health/`): each is an `ICourseHealthCheck` registered in DI and discovered by `CourseHealthService`, so adding one is a class plus a registration line — controller and UI unchanged. Three today: webhook settings (local), GitHub access token (real call to api.github.com, 10s timeout), CI callback token. Checks must not throw; return a `Failed` result instead, or one unreachable course takes the whole dashboard down. A course's status is the worst of its checks. +- **Course health checks** (`Ahk.Web.Services/Health/`): each is an `ICourseHealthCheck` registered in DI and discovered by `CourseHealthService`, so adding one is a class plus a registration line — controller and UI unchanged. Four today: webhook settings (local), GitHub access token (real call to api.github.com, 10s timeout), GitHub App installation, CI callback token. Checks must not throw; return a `Failed` result instead, or one unreachable course takes the whole dashboard down. A course's status is the worst of its checks. - **Dev**: both run HTTPS. The Angular dev proxy (`proxy.conf.js`) forwards `/api/*` to the backend so calls are **same-origin — no CORS**, and `API_BASE_URL` is provided as `''` so generated clients issue relative requests. Press F5 with the **"Full stack (backend + frontend)"** compound in `.vscode/launch.json` to start both. - **Domain model** (`Ahk.Web.Data/Entities`): `Course` 1:1 `CourseGitHubConfig` (per-course GitHub App creds + `WorkflowRunThreshold` — was per-deployment `AHK_*` — plus `GitHubAccessToken`, a PAT used for REST calls that need no installation token, today only the health check); `Student`/`Submission` replace the neptun/repo-name strings; `SubmissionEvent` (TPH: Repository/Branch/PullRequest/WorkflowRun) and `GradeRecord`+`GradeExercisePoint` are **append-only** — current state is projected, never updated. `CourseWebhookToken.Token` is globally unique because the CI callback carries no `{course}` segment; its `Secret` is a plaintext column (HMAC needs the raw key) and the admin API **returns it** (list + detail) so the console can re-copy it later — a deliberate exception to the never-return rule, justified because any admin can mint an equivalent token anyway. - **Assignments** (`Ahk.Web.Data/Entities/Assignment.cs`): student repos are named `{RepoNamePrefix}-{neptun}`, falling back to the template repo's bare name when `RepoNamePrefix` is blank (keeps pre-prefix assignments working) — logic in `AssignmentInviteService.BuildRepositoryName`. The template repo is validated **advisorily** (`AssignmentService.CheckTemplateAsync` → `POST api/{course}/assignments/check-template`): it reports existence + `is_template` as a warning and **never blocks saving** (an assignment may be drafted before its template exists). A bad template otherwise only fails at student-accept time as a 502. +- **Webhook receiver** (`Ahk.Web.Services/GitHubWebhooks/`): `GitHubWebhookDispatcher` selects handlers by `IGitHubWebhookHandler.GitHubEventName`; per-delivery state (course id, delivery id, body, `IGitHubClient`, run threshold) travels on `GitHubWebhookContext`, so handlers are stateless scoped DI registrations. **DI registration order is dispatch order** — that is what replaced github-monitor's explicit config builder, and handlers post comments whose order is visible to students. The `.github/ahk-monitor.yml` `enabled: true` gate and its **12-hour** per-repo-id cache are kept verbatim: adding the file to an already-seen repo takes up to half a day to take effect, and an app restart is the only faster flush. This is the most common cause of "webhook delivers 200 but nothing happens" — read the `WebhookResult` body, it says `no ahk-monitor.yml or disabled`. +- ⚠️ **At most one handler per GitHub event may write a `SubmissionEvent`.** `GitHubDeliveryId` is globally unique (the redelivery guard) but one delivery fans out to several handlers, so a second writer's rows are silently swallowed by the guard, or rejected by the unique index on SQL Server. Handlers that write are marked `IStatusEventWriter` and `WebhookHandlerRegistrationTests` fails the build if two share an event. +- ⚠️ **Course resolution necessarily precedes signature validation** in the webhook receiver: the secret is per course (`CourseGitHubConfig.GitHubWebhookSecret`) and the only thing identifying the course is `repository.full_name` *inside* the body. Everything before the HMAC check is deliberately inert — one property read from a `JsonDocument` that is then disposed, two indexed reads, no writes/GitHub calls/body logging — and every signature failure returns the same 400. Don't add work to that stretch. Benign cases (repo in no course, integration off) answer **202, not 4xx**, because GitHub colours non-2xx red in the delivery log. +- ⚠️ **`AHK_APPURL` must byte-match the CI callback's public URL** (`https://ahk.aut.bme.hu/api/integrations/evaluation-result`): the Go client signs the URL, so scheme, host, path and trailing slash all matter (casing does not — both sides lower it). `http://` fails confusingly, via a 307 and then a scheme mismatch. `UseForwardedHeaders` must stay first in the pipeline for `GetDisplayUrl()` to yield the public URL behind IIS. Full contract in `ahk-backend/docs/ci-callback.md`. +- ⚠️ **`ICourseGitHubAppTokenProvider.GetForCourseAsync(Course)` returns null unless the course was loaded with `Include(c => c.GitHubConfig)`** — it reads `course.GitHubConfig?.GitHubAppId`. `ResolveByRepositoryAsync` does *not* include it, so m2m paths must use the `(int courseId, …)` overload or they silently degrade to "course not connected to GitHub". - ⚠️ **The course query filter matches nothing when no course is resolved.** `ICurrentCourseProvider` is set by whichever entry point resolved the course. Anything without HTTP course context — dev seeder, importer, services — must use `IgnoreQueryFilters()` and filter on `courseId` itself, or it silently reads **zero rows**. Service methods therefore always take an explicit `int courseId` and never read the provider. ## Build, test, run diff --git a/README.md b/README.md index 3d930f09..a923472c 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,13 @@ Please refer to for the concept and details. -## Applications +## The portal + +**[ahk-backend](./ahk-backend)** + **[ahk-frontend](./ahk-frontend)**: a single ASP.NET Core (.NET 10) site with an Angular front end, at `ahk.aut.bme.hu`, replacing the per-course Azure deployments below with one multi-course installation. It now hosts every entry point the original system had — the GitHub webhook receiver, the `/ahk ok` chatops commands and the HMAC-verified CI callback — as well as taking over from GitHub Classroom for handing out student repositories, so a course can run on it with **no Azure Functions**. + +The four applications below remain deployed for courses that have not migrated yet; courses move one at a time. See [Cutover per course](./ahk-backend/docs/github-app.md#cutover-per-course). + +## Applications (the original system) **[GitHub Monitor](./github-monitor)**: An Azure function written in .NET with an http webhook registered as a GitHub Application that manages the workflow of homework submissions. Performs automatic actions on repositories acting as submissions and monitors proper usage of pull requests. diff --git a/ahk-backend/README.md b/ahk-backend/README.md index 7e5cb869..4729c947 100644 --- a/ahk-backend/README.md +++ b/ahk-backend/README.md @@ -5,12 +5,32 @@ per-course Azure Functions deployments with a single site whose domain data is a **Courses**. Provides ASP.NET Identity authentication (local username/password + generic OIDC, cookie-based) and course-scoped, membership-authorized endpoints. -> Milestone status: auth, course-scoping, the domain model and services, the read endpoints, the -> site administration surface (courses, GitHub integration, CI callback tokens, users, health checks) -> and **assignments** (the GitHub Classroom replacement: template repositories, invite links, student -> self-service) are in place. The write-side entry points — the GitHub webhook receiver, `/ahk ok` -> chatops and the HMAC-verified CI callback — are ported in a later milestone. See the architecture -> plan for the full design. +> Milestone status: feature-complete against the original system. Auth, course-scoping, the domain +> model and services, the read endpoints, the site administration surface, **assignments** (the GitHub +> Classroom replacement) and now the write-side entry points — the **GitHub webhook receiver**, **`/ahk +> ok` chatops** and the **HMAC-verified CI callback** — are all in place, so a course can run on the +> portal with no Azure Functions. The four original apps remain in the repository, deployed, for +> courses that have not migrated yet; see [Cutover per course](docs/github-app.md#cutover-per-course). + +## Machine-to-machine endpoints + +Two routes are called by machines rather than by the SPA. Both are anonymous — a signature is the +authentication — and both are excluded from the OpenAPI document, so no TypeScript client is generated +for them. + +| Route | Authenticated by | Resolves its course from | +|---|---|---| +| `POST /api/integrations/github` | `X-Hub-Signature-256`, against the course's own webhook secret | `repository.full_name` in the payload (organization, then repo-name prefix) | +| `POST /api/integrations/evaluation-result` | `X-Ahk-Sha256` over verb + URL + date + body | the `X-Ahk-Token` header — the authenticated credential, not the caller-supplied repository name | + +Neither has a `{course}` path segment, which is why `ICourseResolutionService` exists. See +[docs/github-app.md](docs/github-app.md) and [docs/ci-callback.md](docs/ci-callback.md). + +⚠️ The webhook secret is per course, and the only thing identifying the course is the repository name +*inside* the body — so the receiver has to parse an unverified payload before it can verify it. +Everything before the signature check is deliberately inert: one property is read from a `JsonDocument` +that is then dropped, two indexed reads happen, and nothing is written, logged or called until the HMAC +passes. Keep it that way. ## Projects @@ -19,8 +39,15 @@ cookie-based) and course-scoped, membership-authorized endpoints. `CourseContext/` (course resolution middleware + membership authorization). - **Ahk.Web.Services** — domain logic: grading, status tracking, submission resolution, course resolution, CI callback tokens, `Assignments/` (assignment administration and the student invite - flow), `GitHub/` (the App installation-token provider and the REST calls it authenticates), and - `Health/` (the course health checks). + flow), `GitHub/` (the App installation-token provider and the REST calls it authenticates), + `GitHubWebhooks/` (the webhook dispatcher and the ten rule/status/chatops handlers ported from + `github-monitor`), `Integrations/` (the CI callback's HMAC scheme), and `Health/` (the course + health checks). + + **Octokit** is the portal's GitHub API client — one client, built by `ICourseGitHubClientFactory`. + The single exception is `CourseGitHubAppTokenProvider`, which stays on a raw `HttpClient`: it signs + an App JWT and exchanges it for an installation token, which is the auth bootstrap rather than an + API call, and moving it would change the shape of the permissions the health check reads. - **Ahk.Web.Data** — EF Core `ApplicationDbContext` (Identity + `Course`/`CourseMembership` + `ICourseScoped` global query filter), migrations, and the dev data seeder. - **Ahk.Web.Server.Tests** — xUnit tests (course-scoping unit tests, health-check tests, grade parity diff --git a/ahk-backend/docs/ci-callback.md b/ahk-backend/docs/ci-callback.md new file mode 100644 index 00000000..f8fee89a --- /dev/null +++ b/ahk-backend/docs/ci-callback.md @@ -0,0 +1,133 @@ +# The CI callback + +When the evaluator finishes inside a student's repository, the `publish-results-pr` GitHub Action posts the +result to the portal. This document is the contract between the two. + +It matters more than most internal contracts because **the client cannot be redeployed on our schedule**: it +runs from a workflow file inside student repositories, which are created from a template and then belong to the +student. A change here breaks builds for a cohort that has already started. + +The client is Go (`publish-results-pr/internal/publishtoapi`); the server is +`Ahk.Web.Server/Integrations/EvaluationResultController.cs` and +`Ahk.Web.Services/Integrations/HmacSha256Validator.cs`. The scheme was ported unchanged from +`grade-management`, and both sides' test suites carry the same golden signatures. + +## Endpoint + +``` +POST https://ahk.aut.bme.hu/api/integrations/evaluation-result +``` + +⚠️ **The URL is part of the signature.** Scheme, host, path, trailing slash and any query string all have to +match what the action was configured with. Consequences worth knowing before you debug one of these: + +- **It must be `https`.** An `http://` value gets a 307 from `UseHttpsRedirection`, and even if the client + followed it, the client signed the `http` URL while the server computes the `https` one — a guaranteed + mismatch that looks nothing like a URL problem. +- **No trailing slash**, no extra path segments. +- **Casing is safe** — both sides lower-case the URL before signing. It is the only forgiving part. +- Behind IIS, `UseForwardedHeaders` running first in the pipeline is what makes the server see the *public* + URL rather than the internal one. Do not move it in `Program.cs`. + +## Action configuration + +Set these in the evaluator workflow of each **template** repository: + +| Input | Value | +|---|---| +| `AHK_APPURL` | `https://ahk.aut.bme.hu/api/integrations/evaluation-result` | +| `AHK_APPTOKEN` | The token from **Site administration → Courses → *course* → CI callback tokens** | +| `AHK_APPSECRET` | That token's secret, shown alongside it | + +Publishing is skipped entirely if any of the three is empty, so a template that has not been migrated yet +simply does not report — it does not fail. + +Tokens are per course and can be revoked. Revoking takes effect immediately; the secret lookup is cached for an +hour, and revoking evicts the entry. + +## Headers + +| Header | Purpose | +|---|---| +| `X-Ahk-Token` | Identifies the course. Sent in clear, so it is an identifier, not the secret. | +| `X-Ahk-Sha256` | Base64 HMAC-SHA256 of the string below. | +| `Date` | RFC1123, e.g. `Mon, 02 Jan 2006 15:04:05 GMT`. Signed as well as checked. | +| `X-Ahk-Delivery` | Logged only. Never validated, never used for de-duplication. | + +## The string to sign + +Four parts, joined by single `\n` characters, with **no trailing newline**: + +``` +UPPERCASE(http verb) +lowercase(full url, query string included) +RFC1123 date +raw request body +``` + +Signed with HMAC-SHA256, base64-encoded. The key is the token's secret as **ASCII** bytes — which matches Go's +`[]byte(secret)` for the ASCII-only secrets the generator produces, and is the reason secrets must stay ASCII. + +The `Date` header is checked against the server clock with a **±10 minute** window, and it is also what the +grade is timestamped with — not the moment the server happened to process it. + +## Request body + +```json +{ + "gitHubRepoName": "bmeaut/viaubc01-abc123", + "gitHubBranch": "refs/pull/12/merge", + "gitHubPullRequestNum": 12, + "gitHubCommitHash": "aa11cc33", + "neptunCode": "ABC123", + "imageFiles": [], + "result": [ + { "exerciseName": "ex1", "taskName": "t1", "points": 2, "comment": "ok" }, + { "exerciseName": "ex1", "taskName": "t2", "points": 3 } + ], + "origin": "https://github.com/bmeaut/viaubc01-abc123/commit/aa11cc33" +} +``` + +Two deliberate looseness's, neither of which should be tightened: + +- **Unknown members are ignored.** `imageFiles` has no counterpart on the server and never had one. A strict + deserializer would fail every student build at once. +- **`taskName` is not actually enforced**, despite being marked required, because .NET's validator does not + recurse into collections. It behaved this way in `grade-management` too; enforcing it now would start + rejecting results that pass today. + +`gitHubPullRequestNum` is omitted rather than sent as `0` when there is no pull request. + +### What is stored + +Per-task detail is **discarded**. Points are summed per `exerciseName` (tasks with none collapse into a single +unnamed group) and ordered by name, then written as an **unconfirmed** grade record — it does not appear in the +grade listing or the CSV export until a teacher confirms it with `/ahk ok`. + +## Responses + +`200` with an empty body on success. Everything else is a `400` naming the problem, in this order: + +| Message | Cause | +|---|---| +| `Date header missing` | No `Date` header. | +| `Date header value not valid RFC1123 string` | Malformed date. | +| `Date header value is not close enough to current date` | Runner clock is off by more than 10 minutes. | +| `X-Ahk-Sha256 header missing` | No signature. | +| `X-Ahk-Token header missing` | No token. | +| `X-Ahk-Token invalid` | Unknown token, revoked token, or a token whose course no longer exists. The three are deliberately indistinguishable. | +| `X-Ahk-Sha256 signature not valid` | Wrong secret, or — far more often — the signed URL does not match. See the endpoint section. | +| `Body cannot be deserialized as JSON: …` | Malformed body, or `gitHubRepoName`/`neptunCode` missing. | + +A `500` carries the exception text, because the caller's only view of it is a build log. + +⚠️ **The client treats any non-2xx as fatal and fails the student's build.** That is why an unknown repository +is not an error — the submission row is created on first sighting — and why a bad token is worth catching with +the health check before students meet it. + +## Diagnosing a signature mismatch + +The server logs the *URL component* of the string it signed at `Debug` level when a signature fails. Never the +body (it is student code) and never the secret. In practice the URL is the culprit almost every time; compare +it against `AHK_APPURL` character by character. diff --git a/ahk-backend/docs/github-app.md b/ahk-backend/docs/github-app.md index 8b42b9b3..e32fd056 100644 --- a/ahk-backend/docs/github-app.md +++ b/ahk-backend/docs/github-app.md @@ -21,11 +21,12 @@ The App is used for two things: | Purpose | Status | |---|---| -| Receiving webhooks (pushes, pull requests, comments, workflow runs) and enforcing the course's rules | Live today in `github-monitor`; the receiver is **not yet ported** to the portal | -| Creating student repositories from an assignment's template and granting students access | Live in the portal (this feature) | +| Receiving webhooks (pull requests, comments, workflow runs) and enforcing the course's rules | Live in the portal | +| Creating student repositories from an assignment's template and granting students access | Live in the portal | -One App can serve both. If the organization already has an App registered for `github-monitor`, extend that one -rather than registering a second — see [Permissions](#permissions) for the single grant that has to be added. +One App serves both. If the organization already has an App registered for `github-monitor`, extend that one +rather than registering a second — see [Permissions](#permissions) for the grant that has to be added — and +repoint its webhook URL as described in [Cutover per course](#cutover-per-course). ## Registering the App @@ -36,14 +37,17 @@ Do this once per organization, as an organization owner. 3. **Homepage URL** — `https://ahk.aut.bme.hu`. 4. **Webhook** - Tick **Active**. - - **Webhook URL**: `https://ahk.aut.bme.hu/api/integrations/github`. - ⚠️ This path is reserved but **the receiver is not implemented in the portal yet**. Until it is, point the - webhook at the course's existing `github-monitor` Function URL instead, and keep using that. + - **Webhook URL**: `https://ahk.aut.bme.hu/api/integrations/github` + - **Content type**: `application/json`. - **Webhook secret**: generate a long random string. You will need it again in step 8. + There is no global secret — the receiver validates `X-Hub-Signature-256` against **that course's** stored + secret, and resolves which course a delivery belongs to from the repository name inside it. 5. **Permissions** — set exactly what the [table below](#permissions) lists. Nothing more: an App with rights nobody uses is a liability, and organization owners are shown this list when they install it. -6. **Subscribe to events** — only needed for the webhook side: *Pull request*, *Pull request review*, - *Issue comment*, *Push*, *Create*, *Repository*, *Workflow run*. +6. **Subscribe to events** — the five the portal has handlers for: *Create*, *Issue comment*, *Pull request*, + *Pull request review*, *Workflow run*. + Subscribing to more is harmless — anything else is answered `200` with `Event X is not of interest` — but it + makes the delivery log noisier to read. 7. **Where can this GitHub App be installed?** — *Only on this account*. 8. Create it, then on the App's page: - Note the **App ID**. @@ -66,12 +70,12 @@ Set these under **Repository permissions**. Organization permissions are not nee | Permission | Level | Why | |---|---|---| -| **Administration** | **Read & write** | Creating a repository from a template (`POST /repos/{owner}/{repo}/generate`), adding a student as a collaborator (`PUT /repos/{owner}/{repo}/collaborators/{username}`), managing their invitations, and setting a repository's Actions permissions all sit behind this one. **This is the grant to add if the App already exists for `github-monitor`.** | +| **Administration** | **Read & write** | Creating a repository from a template (`POST /repos/{owner}/{repo}/generate`), adding a student as a collaborator (`PUT /repos/{owner}/{repo}/collaborators/{username}`), managing their invitations, setting a repository's Actions permissions, and applying branch protection all sit behind this one. **This is the grant to add if the App already exists for `github-monitor`.** | | **Metadata** | Read-only | Mandatory for every App. Also backs `GET /repos/{owner}/{repo}`, which the portal uses to check the template exists and is marked as a template. | -| **Contents** | Read-only | Reading the template repository. `github-monitor` needs **Read & write** here for its own work. | -| Pull requests | Read & write | `github-monitor` only: comments, merges, assignees. | -| Issues | Read & write | `github-monitor` only: issue comments carry the `/ahk ok` chatops. | -| Actions | Read-only | `github-monitor` only: counting workflow runs against the course threshold. | +| **Contents** | Read & write | Reading the template repository, and reading `.github/ahk-monitor.yml` and `neptun.txt` out of each student repository. | +| Pull requests | Read & write | Comments, merges, assignees — the `/ahk ok` command approves and merges. | +| Issues | Read & write | Issue comments carry the `/ahk ok` chatops and every warning the rules post. | +| Actions | Read-only | Counting workflow runs against the course's threshold. | Note that **Administration: write is broad** — it also permits changing repository settings and deleting repositories. There is no narrower permission that covers creating repositories and adding collaborators, so @@ -109,17 +113,45 @@ Each call runs as the App's *installation* on the course's organization: The App JWT never leaves step 1–3; every repository operation uses the installation token. The code is `Ahk.Web.Services/GitHub/CourseGitHubAppTokenProvider.cs`. +Note the installation is looked up **from the organization**, not from the `installation.id` a webhook delivery +carries. The course is resolved *by* organization, so the two are the same installation by construction — and +deriving a credential from a payload field would be a weaker path to the same answer. A mismatch is logged as a +warning and otherwise ignored. + +## Delivery responses + +What the receiver answers, and what each status means when you read it in **Advanced → Recent Deliveries**. +Only the first two are normal. + +| Status | Body | Meaning | +|---|---|---| +| `200` | one line per handler | Delivered and processed. Read the lines: `no action needed` and `action not of interest` are both normal, and `event handler disabled: no ahk-monitor.yml or disabled` means the repository is not opted in. | +| `202` | `repository '…' is not mapped to a course` | The repository's organization (and repo-name prefix) match no course. Normal for repositories in the organization that are not coursework. | +| `202` | `GitHub integration is not configured` / `is turned off` | The course exists but has no GitHub integration saved, or it is switched off. **A course switched off silently ignores `/ahk ok`.** | +| `400` | `Payload signature not valid` | The secret stored on the course does not match the one on the App. | +| `400` | `X-GitHub-Event header missing` etc. | Something other than GitHub is posting, or the webhook is configured with the wrong content type. | +| `500` | `GitHub secret not configured` | The course has an organization but no webhook secret stored. Finish *Storing the credentials* below. | +| `500` | `GitHub App ID/Token not configured` | The App id or private key is missing or invalid, so no installation token could be minted. | + +Benign cases answer `202` rather than an error on purpose: GitHub colours every non-2xx red, and a delivery log +full of red is a log nobody reads. + ## Template repository requirements An assignment points at a template repository in the course's organization. It must: - be marked **Template repository** in its Settings (`is_template: true`) — without this GitHub refuses the generate call outright; -- contain the evaluator workflow under `.github/workflows/`; -- contain `.github/ahk-monitor.yml` with `enabled: true`, or `github-monitor` will ignore every event from the - repositories generated from it; +- contain the evaluator workflow under `.github/workflows/`, with `AHK_APPURL` pointing at the portal (see + [ci-callback.md](ci-callback.md)); +- contain `.github/ahk-monitor.yml` with `enabled: true`, or **every event from repositories generated from it + is ignored**; - have the branch students should start from as its **default branch** — only that branch is copied. +⚠️ The opt-in answer is cached for **12 hours** per repository. Adding `ahk-monitor.yml` to a repository that +has already been seen therefore takes up to half a day to take effect; restarting the application is the only +faster flush. This is the most common reason a correctly wired webhook appears to do nothing. + The assignment editor checks the first point when you save, and reports it as a warning rather than blocking: an assignment may legitimately be drafted before its template exists. @@ -165,3 +197,37 @@ Specific failures: - **“limited to selected repositories”** — change the installation's repository access to *All repositories*. - **Student says the repository 404s** — they almost certainly have an unaccepted invitation. Point them at `/my` on the portal. +- **Every delivery is `405` with `Allow: GET, HEAD`** — the webhook URL points at the portal but not at + `/api/integrations/github`. The request fell through to the Angular single-page app's fallback route, which + only answers GET. Check the path, including that it has no trailing slash. +- **Deliveries are `200` but nothing happens** — read the response body. `no ahk-monitor.yml or disabled` means + the repository is not opted in; mind the 12-hour cache noted above. +- **No deliveries at all** — the App's installation is limited to *selected repositories*, so a repository + created after the installation falls outside it. Or the event is not one of the five subscribed. + +## Cutover per course + +⚠️ **A GitHub App has exactly one webhook URL, so for a single course this is a flip, not a parallel run.** +Courses migrate independently — course A can stay on `github-monitor` while course B is on the portal — but one +course cannot be served by both at once. Doing that would need a second App registration or an +organization-level webhook. + +1. Store the App id, private key, webhook secret, `WorkflowRunThreshold` and **Enabled** under + **Site administration → Courses → *course* → GitHub integration**. +2. Check all four health checks are green on **Site administration → Health**. +3. Make sure the course has a non-revoked CI callback token (mint one, or import the legacy one — the + `Ahk.Web.Import` tool already imports tokens). +4. Import the course's historical Cosmos data, if that has not been done. +5. **Flip** the App's webhook URL to `https://ahk.aut.bme.hu/api/integrations/github` and trim the subscribed + events to the five listed above. Use the **Redeliver** button on a recent delivery to test without waiting + for a student. +6. Smoke test on a scratch repository in the organization: push a branch (a branch event should appear under + the course's dashboard), open a pull request, and comment `/ahk ok 5` as an organization member — the pull + request should be approved and merged, and a grade should appear. +7. Update the course's **template** repositories' evaluator workflow: `AHK_APPURL`, `AHK_APPTOKEN` and + `AHK_APPSECRET` (see [ci-callback.md](ci-callback.md)). +8. ⚠️ **Student repositories already generated keep the old workflow** and go on posting results to + `grade-management`. Either leave that deployment running until the cohort finishes, or push a workflow + update across the existing student repositories. Decide this *before* step 7 and record the decision. +9. Leave `github-monitor` and `grade-management` deployed until every course has migrated and the semester has + closed. From 124145058bd6eab9f3f63a26e05a86dbe9c247ab Mon Sep 17 00:00:00 2001 From: Bence Kovari Date: Sun, 9 Aug 2026 02:06:12 +0200 Subject: [PATCH 15/19] claude settings --- .claude/settings.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.claude/settings.json b/.claude/settings.json index f1cd7915..17c1ac09 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -103,7 +103,11 @@ "Bash(wsl.exe bash *)", "Bash(node shot5.mjs)", "Bash(git add *)", - "Bash(git commit *)" + "Bash(git commit *)", + "Bash(curl -sk -o /dev/null -w \"\" https://localhost:7443/swagger/v1/swagger.json)", + "Bash(break)", + "Bash(curl -sk -X POST https://localhost:7443/api/integrations/github -H 'Content-Type: application/json' -d '{}' -w \"\\\\nHTTP %{http_code}\\\\n\")", + "Bash(curl -sk -X POST https://localhost:7443/api/integrations/evaluation-result -H 'Content-Type: application/json' -d '{}' -w \"\\\\nHTTP %{http_code}\\\\n\")" ], "additionalDirectories": [ "\\tmp", From cf75e8c6658b57ed0d7607f97af754083e5185e0 Mon Sep 17 00:00:00 2001 From: Bence Kovari Date: Sun, 9 Aug 2026 02:12:23 +0200 Subject: [PATCH 16/19] docs: record this session's working learnings in CLAUDE.md Five additions, each one something that cost a build or a test run: - How to probe a NuGet package's API surface here, and that the XML doc file is partial so absence from it proves nothing. Plus the two Octokit 14 facts found that way (no IncludeAllBranches; IsTemplate/Expired are non-nullable). - A curl + openssl recipe for exercising the webhook and CI callback by hand, with the dev seeder's org and secret. This is the fastest path for the next person debugging a delivery, and viaubb01 having no secret on purpose makes it a ready-made test of the failure branch. - That `git add -A` at the repo root stages .claude/settings.json, which shares permission grants with everyone who clones. Learned by doing it. - Test patterns for the m2m endpoints: build Octokit models by deserializing GitHub's JSON rather than through their constructors, which of the DI registrations WebApplicationFactory has to replace, and two MSTest-to-xUnit traps (no params in InlineData; HttpClient refuses to send a malformed Date). - That both signature comparisons must stay constant-time. The Azure Functions use string.Equals, so a future "restore parity" instinct would quietly undo a security fix - worth stating rather than leaving to a code comment. Co-Authored-By: Claude Opus 5 --- CLAUDE.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index ee7e7d1d..d4eaa65a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -70,6 +70,7 @@ Design decisions (rationale in the architecture plan and `ahk-backend/README.md` - **Webhook receiver** (`Ahk.Web.Services/GitHubWebhooks/`): `GitHubWebhookDispatcher` selects handlers by `IGitHubWebhookHandler.GitHubEventName`; per-delivery state (course id, delivery id, body, `IGitHubClient`, run threshold) travels on `GitHubWebhookContext`, so handlers are stateless scoped DI registrations. **DI registration order is dispatch order** — that is what replaced github-monitor's explicit config builder, and handlers post comments whose order is visible to students. The `.github/ahk-monitor.yml` `enabled: true` gate and its **12-hour** per-repo-id cache are kept verbatim: adding the file to an already-seen repo takes up to half a day to take effect, and an app restart is the only faster flush. This is the most common cause of "webhook delivers 200 but nothing happens" — read the `WebhookResult` body, it says `no ahk-monitor.yml or disabled`. - ⚠️ **At most one handler per GitHub event may write a `SubmissionEvent`.** `GitHubDeliveryId` is globally unique (the redelivery guard) but one delivery fans out to several handlers, so a second writer's rows are silently swallowed by the guard, or rejected by the unique index on SQL Server. Handlers that write are marked `IStatusEventWriter` and `WebhookHandlerRegistrationTests` fails the build if two share an event. - ⚠️ **Course resolution necessarily precedes signature validation** in the webhook receiver: the secret is per course (`CourseGitHubConfig.GitHubWebhookSecret`) and the only thing identifying the course is `repository.full_name` *inside* the body. Everything before the HMAC check is deliberately inert — one property read from a `JsonDocument` that is then disposed, two indexed reads, no writes/GitHub calls/body logging — and every signature failure returns the same 400. Don't add work to that stretch. Benign cases (repo in no course, integration off) answer **202, not 4xx**, because GitHub colours non-2xx red in the delivery log. +- ⚠️ **Both signature comparisons must stay constant-time** (`SignatureComparison.FixedTimeEquals`). The Azure Functions used `string.Equals`, which returns at the first differing character and lets a forged signature be refined a character at a time by timing — do not "restore parity" here. Same reason the CI callback logs only a masked last-four of the caller's token, where grade-management logged it whole. - ⚠️ **`AHK_APPURL` must byte-match the CI callback's public URL** (`https://ahk.aut.bme.hu/api/integrations/evaluation-result`): the Go client signs the URL, so scheme, host, path and trailing slash all matter (casing does not — both sides lower it). `http://` fails confusingly, via a 307 and then a scheme mismatch. `UseForwardedHeaders` must stay first in the pipeline for `GetDisplayUrl()` to yield the public URL behind IIS. Full contract in `ahk-backend/docs/ci-callback.md`. - ⚠️ **`ICourseGitHubAppTokenProvider.GetForCourseAsync(Course)` returns null unless the course was loaded with `Include(c => c.GitHubConfig)`** — it reads `course.GitHubConfig?.GitHubAppId`. `ResolveByRepositoryAsync` does *not* include it, so m2m paths must use the `(int courseId, …)` overload or they silently degrade to "course not connected to GitHub". - ⚠️ **The course query filter matches nothing when no course is resolved.** `ICurrentCourseProvider` is set by whichever entry point resolved the course. Anything without HTTP course context — dev seeder, importer, services — must use `IgnoreQueryFilters()` and filter on `courseId` itself, or it silently reads **zero rows**. Service methods therefore always take an explicit `int courseId` and never read the provider. @@ -137,8 +138,11 @@ npm run generate-api # regenerate src/app/api from the backend's OpenAPI (back - **`sqlcmd` needs `SET QUOTED_IDENTIFIER ON`** before DML on `AspNetUsers`/`SubmissionEvents` — the filtered unique index on `GitHubDeliveryId` makes the default fail. - **Auth cookies are named `ahk.auth` / `ahk.auth.external`, not the framework defaults** (`Program.ApplicationCookieName`). Browsers scope cookies by host and **ignore the port**, so on `localhost` every ASP.NET Identity app shares `.AspNetCore.Identity.Application`. A cookie from another project whose user id is a GUID reaches this int-keyed app and throws `"… is not a valid value for Int32"` inside `SecurityStampValidator` — a 500 on *every* request, including login. `OnValidatePrincipal` also wraps the stamp validator so an unreadable cookie signs the caller out instead of throwing. Do not revert either to the defaults. - **Windows PowerShell 5.1 cannot load .NET 10 assemblies** (`Add-Type` throws); to find a type's namespace, `grep -ao` the DLL instead. +- **To probe a NuGet package's API surface**, read `~/.nuget/packages///lib//*.xml` (`grep -o 'name="M:Type\.[^"]*"'`) — but it is **partial**, many members have no doc entry, so absence there proves nothing; fall back to `grep -a` on the DLL for a member name, or just write the call and let the compiler answer. Octokit 14 facts found this way: `NewRepositoryFromTemplate` has **no** `IncludeAllBranches` (GitHub defaults it false, which is what we want), and `Repository.IsTemplate` / `RepositoryInvitation.Expired` are **non-nullable** `bool`. - **No Docker in this environment** — dev dependencies are built in-app (e.g. the mock OIDC provider), not containerized. - **Verify UI changes by screenshotting the running app**, not by trusting the build. Chrome is at `/c/Program Files/Google/Chrome/Application/chrome.exe`. A plain `--headless=new --screenshot` fires before Angular hydrates and yields a near-empty page — add `--virtual-time-budget=4000`. For screens behind login, start Chrome with `--remote-debugging-port=9222` and drive the DevTools protocol from a Node script: Node 24 ships a built-in `WebSocket`, so this needs no npm dependency. Always pass `--ignore-certificate-errors` (self-signed dev cert). When reading a value back from `Runtime.evaluate`, the RemoteObject is doubly nested at `msg.result.result.value` — reading `msg.result.value` silently yields `undefined` (the clicks still fire, so screenshots look fine while probes read blank). +- **Exercise the m2m endpoints by hand** against the running backend — faster than the GitHub UI and it works offline. Sign with `openssl`: ``SIG="sha256=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac 'dev-webhook-secret' -hex | sed 's/.*= //')"``, then `curl -sk -X POST https://localhost:7443/api/integrations/github -H 'X-GitHub-Event: ping' -H "X-Hub-Signature-256: $SIG" -d "$BODY"`. The dev seeder's `viaubc01` is org **`ahk-viaubc01`**, secret **`dev-webhook-secret`**; `viaubb01` deliberately has **no** secret, so it exercises the 500 branch. +- **Scope `git add` to the app directory.** `git add -A` at the repo root also stages `.claude/settings.json`, which the harness rewrites whenever a permission is granted — committing it silently shares those grants with everyone who clones (it is the checked-in project file; `settings.local.json` is the personal one). - **No image tooling** — no PIL, no ImageMagick. To read a PNG's pixels (sampling a brand colour, checking dimensions) decode it by hand with `zlib` + `struct`. EPS files are text-ish: `%%CMYKCustomColor` in the header carries the print colour spec. - **Prod hosting is same-origin**: the backend serves the Angular SPA — `UseDefaultFiles`/`UseStaticFiles` + `MapFallbackToFile("index.html")` in `Program.cs`, `ng build` output copied into `wwwroot`. Only dev uses the proxy. - **`web.config` is checked in with its SDK transform disabled** (`IsTransformWebConfigDisabled=true`): Mezga registers ANCM under the **V1** name `AspNetCoreModule`, so the SDK-generated V2 web.config fails to start the app there. Don't delete the file or re-enable the transform. @@ -172,4 +176,5 @@ The portal has its own `ahk-web-deploy.yaml` (manual `workflow_dispatch`): publi - **Portal code style**: **no top-level statements** (`Program` is an explicit class with `Main`); **`int` keys everywhere**, including Identity (`IdentityUser`); the domain term is **Course**, never "tenant". - **Frontend API errors**: use `readApiError(err, fallback)` from `ahk-frontend/src/app/core/api-error.ts` instead of parsing a `SwaggerException` inline. It pulls out the API's own `{error}`/`{errors}` message and reports status 0 as "the server is not responding" — without that, a generated-client failure surfaces as a misleading domain error (a stopped backend once looked exactly like "wrong password"). - **Portal tests**: course-scoping is tested against `ApplicationDbContext` directly with EF InMemory + a mutable `ICurrentCourseProvider` double. `WebApplicationFactory` DbContext swaps must remove **both** `DbContextOptions` and EF 9+'s `IDbContextOptionsConfiguration` descriptors, else two providers register. `Ahk.Web.Services` exposes internals via `InternalsVisibleTo`. Frontend single run: `npx ng test --watch=false`. Controller tests can run over a real `UserManager` on EF InMemory (see `UserNeptunTests`) — but InMemory does **not** enforce filtered unique indexes, so uniqueness is proven via the controller's pre-check, not the DB. +- **Testing the m2m endpoints**: build Octokit models by **deserializing the JSON GitHub would send** — `new SimpleJsonSerializer().Deserialize(json)` — rather than through their long constructors. `WebApplicationFactory` must also remove `ICourseGitHubAppTokenProvider` / `ICourseGitHubClientFactory` (so nothing reaches api.github.com) and `TimeProvider` (swap in `FakeTimeProvider` from `Microsoft.Extensions.TimeProvider.Testing`). Two porting traps: xUnit `[InlineData]` has **no `params`** — MSTest `[DataRow(…, 1, 2)]` becomes `[InlineData(…, new[] { 1d, 2d })]`; and `HttpClient` parses the `Date` header itself and **refuses to send a malformed one**, so reaching the "not valid RFC1123" branch needs `TryAddWithoutValidation`. - **Legacy parity is a hard constraint when porting**: grade semantics (append-only, positional `ex0`/`ex1` name carry-forward, per-exercise summing) and the CSV layout are covered by parity tests — changing them changes existing courses' grades. One deliberate deviation: `CsvExporter` sorts columns `Ordinal` rather than culture-sensitively. From a28be32af3ca576df10052474dbc481b3c857e2c Mon Sep 17 00:00:00 2001 From: Bence Kovari Date: Sun, 9 Aug 2026 02:16:10 +0200 Subject: [PATCH 17/19] update claude md --- CLAUDE.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index d4eaa65a..b1516878 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,6 +2,10 @@ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. +## Working in this repo + +⚠️ **Do not run git write commands.** No `git add`, `git commit`, `git checkout`, `git reset`, `git stash`, `git merge`, `git push` — the maintainer commits by hand, deliberately, and wants to review and stage the working tree themselves. Leave changes uncommitted in the working tree and say what you changed. Read-only inspection (`git status`, `git diff`, `git log`, `git show`) is fine and useful. + ## What this is **Ahk** = automated homework evaluation. A toolset that automates homework submission, evaluation, and grading using GitHub, GitHub Classroom, and GitHub Actions. Concept docs: @@ -142,7 +146,6 @@ npm run generate-api # regenerate src/app/api from the backend's OpenAPI (back - **No Docker in this environment** — dev dependencies are built in-app (e.g. the mock OIDC provider), not containerized. - **Verify UI changes by screenshotting the running app**, not by trusting the build. Chrome is at `/c/Program Files/Google/Chrome/Application/chrome.exe`. A plain `--headless=new --screenshot` fires before Angular hydrates and yields a near-empty page — add `--virtual-time-budget=4000`. For screens behind login, start Chrome with `--remote-debugging-port=9222` and drive the DevTools protocol from a Node script: Node 24 ships a built-in `WebSocket`, so this needs no npm dependency. Always pass `--ignore-certificate-errors` (self-signed dev cert). When reading a value back from `Runtime.evaluate`, the RemoteObject is doubly nested at `msg.result.result.value` — reading `msg.result.value` silently yields `undefined` (the clicks still fire, so screenshots look fine while probes read blank). - **Exercise the m2m endpoints by hand** against the running backend — faster than the GitHub UI and it works offline. Sign with `openssl`: ``SIG="sha256=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac 'dev-webhook-secret' -hex | sed 's/.*= //')"``, then `curl -sk -X POST https://localhost:7443/api/integrations/github -H 'X-GitHub-Event: ping' -H "X-Hub-Signature-256: $SIG" -d "$BODY"`. The dev seeder's `viaubc01` is org **`ahk-viaubc01`**, secret **`dev-webhook-secret`**; `viaubb01` deliberately has **no** secret, so it exercises the 500 branch. -- **Scope `git add` to the app directory.** `git add -A` at the repo root also stages `.claude/settings.json`, which the harness rewrites whenever a permission is granted — committing it silently shares those grants with everyone who clones (it is the checked-in project file; `settings.local.json` is the personal one). - **No image tooling** — no PIL, no ImageMagick. To read a PNG's pixels (sampling a brand colour, checking dimensions) decode it by hand with `zlib` + `struct`. EPS files are text-ish: `%%CMYKCustomColor` in the header carries the print colour spec. - **Prod hosting is same-origin**: the backend serves the Angular SPA — `UseDefaultFiles`/`UseStaticFiles` + `MapFallbackToFile("index.html")` in `Program.cs`, `ng build` output copied into `wwwroot`. Only dev uses the proxy. - **`web.config` is checked in with its SDK transform disabled** (`IsTransformWebConfigDisabled=true`): Mezga registers ANCM under the **V1** name `AspNetCoreModule`, so the SDK-generated V2 web.config fails to start the app there. Don't delete the file or re-enable the transform. From b2f69e5c51c3d3a74f767777cb6a4fece9e4e85a Mon Sep 17 00:00:00 2001 From: Bence Kovari Date: Sun, 9 Aug 2026 02:34:27 +0200 Subject: [PATCH 18/19] update webdeploy action --- .claude/settings.json | 6 +- .github/workflows/ahk-web-deploy.yaml | 92 +++++++++++++++++++++++++-- 2 files changed, 93 insertions(+), 5 deletions(-) diff --git a/.claude/settings.json b/.claude/settings.json index 17c1ac09..f55f22a2 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -107,7 +107,11 @@ "Bash(curl -sk -o /dev/null -w \"\" https://localhost:7443/swagger/v1/swagger.json)", "Bash(break)", "Bash(curl -sk -X POST https://localhost:7443/api/integrations/github -H 'Content-Type: application/json' -d '{}' -w \"\\\\nHTTP %{http_code}\\\\n\")", - "Bash(curl -sk -X POST https://localhost:7443/api/integrations/evaluation-result -H 'Content-Type: application/json' -d '{}' -w \"\\\\nHTTP %{http_code}\\\\n\")" + "Bash(curl -sk -X POST https://localhost:7443/api/integrations/evaluation-result -H 'Content-Type: application/json' -d '{}' -w \"\\\\nHTTP %{http_code}\\\\n\")", + "Bash(node -e ' *)", + "Bash(python3 -c ' *)", + "Bash(MSYS_NO_PATHCONV=1 wsl.exe bash __TRACKED_VAR__/harness.sh __TRACKED_VAR__/apply-step.sh)", + "Bash(MSYS_NO_PATHCONV=1 wsl.exe bash __TRACKED_VAR__/harness-edge.sh __TRACKED_VAR__/apply-step.sh)" ], "additionalDirectories": [ "\\tmp", diff --git a/.github/workflows/ahk-web-deploy.yaml b/.github/workflows/ahk-web-deploy.yaml index e5352bb7..28dfbb9c 100644 --- a/.github/workflows/ahk-web-deploy.yaml +++ b/.github/workflows/ahk-web-deploy.yaml @@ -230,28 +230,112 @@ jobs: - name: Apply changed files if: steps.diff.outputs.has_changes == 'true' run: | + set -o pipefail + + changed_count=$(wc -l < changed.list) + removed_count=$(wc -l < removed.list) + + # Bytes about to cross the tunnel. A self-contained publish is a handful of very large files + # plus a long tail, so "which files" explains a slow run far better than "how many". + changed_bytes=0 + if [ -s changed.list ]; then + changed_bytes=$(sed 's|^|publish/|' changed.list | tr '\n' '\0' \ + | xargs -0 -r stat -c %s 2>/dev/null | awk '{s+=$1} END {print s+0}') + fi + + echo "Copying $changed_count file(s), $(numfmt --to=iec --suffix=B "$changed_bytes"); deleting $removed_count." + + if [ -s changed.list ]; then + echo "::group::Ten largest files in this transfer" + sed 's|^|publish/|' changed.list | tr '\n' '\0' \ + | xargs -0 -r stat -c '%s %n' 2>/dev/null \ + | sort -rn | head -10 \ + | awk '{ size=$1; $1=""; sub(/^ /,""); printf "%10s %s\n", size, $0 }' \ + | numfmt --to=iec --suffix=B --field=1 || true + echo "::endgroup::" + fi + + # Millisecond resolution: a fast deploy still has to report a throughput figure, otherwise + # there is no baseline to compare a slow one against. + copy_ms=0 + attempts=0 if [ -s changed.list ]; then ok=0 + copy_start=$(date +%s%3N) for i in $(seq 1 10); do + attempts=$i + echo "::group::rsync attempt $i" + attempt_start=$(date +%s%3N) + # --out-format stamps every file with the wall-clock time it landed, which is what turns + # "the deploy was slow" into "it stalled for 90s on this one file". --stats reports the + # effective transfer rate over the tunnel. if rsync -R --files-from=changed.list --ignore-times --whole-file --inplace \ - --no-perms --no-owner --no-group --no-times publish/ "$MOUNT_POINT/"; then - ok=1; break + --no-perms --no-owner --no-group --no-times \ + --stats --human-readable --out-format='%t %12l %n' \ + publish/ "$MOUNT_POINT/"; then + ok=1 + echo "Attempt $i succeeded in $(( ($(date +%s%3N) - attempt_start) / 1000 ))s" + echo "::endgroup::" + break fi - echo "rsync attempt $i failed (likely a locked file); retrying..." + echo "::endgroup::" + echo "::warning::rsync attempt $i failed after $(( ($(date +%s%3N) - attempt_start) / 1000 ))s (likely a locked file); retrying..." sleep 2 done + copy_ms=$(( $(date +%s%3N) - copy_start )) + if [ "$ok" -ne 1 ]; then - echo "::error::Copying changed files failed after retries" + echo "::error::Copying changed files failed after $attempts attempts and $(( copy_ms / 1000 ))s" exit 1 fi fi + # Deletes are one CIFS round-trip each, so a large prune is latency-bound rather than + # bandwidth-bound and is worth timing separately from the copy. + delete_ms=0 if [ -s removed.list ]; then + delete_start=$(date +%s%3N) while IFS= read -r path; do rm -f "$MOUNT_POINT/$path" done < removed.list + delete_ms=$(( $(date +%s%3N) - delete_start )) + echo "Deleted $removed_count file(s) in $(( delete_ms / 1000 ))s" fi + # Both rates matter, and which one is poor says where the bottleneck is: low MB/s with + # healthy files/s means the link is the limit; low files/s with healthy MB/s means CIFS + # round-trip latency is, and the fix is fewer files rather than smaller ones. + summary=$(awk -v n="$changed_count" -v b="$changed_bytes" -v cms="$copy_ms" \ + -v dn="$removed_count" -v dms="$delete_ms" ' + BEGIN { + mb = b / 1048576 + cs = cms / 1000 + ds = dms / 1000 + printf "| Metric | Value |\n|---|---|\n" + printf "| Files copied | %d |\n", n + printf "| Bytes copied | %.1f MB |\n", mb + printf "| Copy time | %.1fs |\n", cs + if (cs > 0) { + printf "| Throughput | %.2f MB/s |\n", mb / cs + printf "| File rate | %.1f files/s |\n", n / cs + } + printf "| Files deleted | %d |\n", dn + printf "| Delete time | %.1fs |\n", ds + if (ds > 0) printf "| Delete rate | %.1f files/s |\n", dn / ds + printf "| Total | %.1fs |\n", cs + ds + }') + + echo "$summary" + { + echo "### Applying changed files" + echo "" + echo "$summary" + if [ "$attempts" -gt 1 ]; then + echo "" + echo "⚠️ rsync needed **$attempts attempts** — retries re-send every file, so each one costs a full copy." + fi + } >> "$GITHUB_STEP_SUMMARY" + - name: Wake site (remove app_offline.htm) if: steps.diff.outputs.has_changes == 'true' run: rm -f "$MOUNT_POINT/app_offline.htm" From c434fd47fce7ee410deaa294ec26d6b966195462 Mon Sep 17 00:00:00 2001 From: Bence Kovari Date: Sun, 9 Aug 2026 13:40:45 +0200 Subject: [PATCH 19/19] github workflows --- .../workflows/publish-result-pr-build.yaml | 20 +++-- .../publish-result-pr-docker-publish.yaml | 79 +++++++++++++++++-- CLAUDE.md | 2 +- README.md | 2 +- ahk-backend/docs/github-app.md | 12 ++- publish-results-pr/README.md | 8 +- 6 files changed, 100 insertions(+), 23 deletions(-) diff --git a/.github/workflows/publish-result-pr-build.yaml b/.github/workflows/publish-result-pr-build.yaml index 002eb613..aea4d52e 100644 --- a/.github/workflows/publish-result-pr-build.yaml +++ b/.github/workflows/publish-result-pr-build.yaml @@ -5,27 +5,25 @@ on: paths: - "publish-results-pr/**" +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 + # setup-go v4 and later cache the module and build caches itself, keyed on the checksum file, which + # is why the separate actions/cache step this workflow used to carry is gone. go.sum is not at the + # repository root in this monorepo, so the path has to be given explicitly. - name: Go setup - uses: actions/setup-go@v2 + uses: actions/setup-go@v5 with: go-version: "1.17" - - - uses: actions/cache@v2 - with: - path: | - ~/.cache/go-build - ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- + cache-dependency-path: publish-results-pr/go.sum - name: Build working-directory: publish-results-pr diff --git a/.github/workflows/publish-result-pr-docker-publish.yaml b/.github/workflows/publish-result-pr-docker-publish.yaml index d531a985..230af3c3 100644 --- a/.github/workflows/publish-result-pr-docker-publish.yaml +++ b/.github/workflows/publish-result-pr-docker-publish.yaml @@ -1,19 +1,84 @@ name: Publish Result PR - Docker publish -on: [workflow_dispatch] +on: + workflow_dispatch: + inputs: + tag: + description: "Moving tag to publish. Student repositories resolve this at run time, so publishing it changes every course at once." + type: string + default: "v1" + +env: + # Published under bmeaut, the organization that owns this source. + # + # It previously lived in a personal namespace (ghcr.io/akosdudas/...) belonging to someone who has since + # left the university, so the account — and with it every course's evaluation pipeline — was outside our + # control. Images built here are course-critical; they belong to the organization, not to a person. + # + # ⚠️ Student repositories generated before this move still reference the old image and keep working until + # that account's package disappears. Migrating them means editing the `uses:` line in each repository's + # workflow — the same pass that sets AHK_APPURL. See ahk-backend/docs/ci-callback.md. + IMAGE: ghcr.io/bmeaut/ahk-publish-results-pr jobs: publish: runs-on: ubuntu-latest + # GITHUB_TOKEN is read-only by default in many organizations; without packages:write the push fails + # with a permission error that reads like an authentication problem. + permissions: + contents: read + packages: write + steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 + + - name: Log in to GHCR + run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin + + # The moving tag is what every student repository resolves at run time, so overwriting it changes + # behaviour everywhere simultaneously and there is no built-in way back. Park the outgoing image + # under a fixed name first, so a bad publish is one `docker buildx imagetools create` from undone. + - name: Preserve the outgoing image as :${{ inputs.tag }}-previous + run: | + if docker pull "$IMAGE:${{ inputs.tag }}"; then + docker tag "$IMAGE:${{ inputs.tag }}" "$IMAGE:${{ inputs.tag }}-previous" + docker push "$IMAGE:${{ inputs.tag }}-previous" + echo "Previous image preserved as $IMAGE:${{ inputs.tag }}-previous" + else + echo "No existing $IMAGE:${{ inputs.tag }} — nothing to preserve (first publish under this namespace)." + fi - - name: Build and push to GHCR + - name: Build working-directory: publish-results-pr run: | - echo "${{ secrets.GITHUB_TOKEN }}" | docker login https://ghcr.io -u ${{ github.actor }} --password-stdin - docker build -t ghcr.io/akosdudas/ahk-publish-results-pr:v1 . - docker push ghcr.io/akosdudas/ahk-publish-results-pr:v1 - docker logout https://ghcr.io + # Also tagged with the commit, which is immutable: it gives every publish a permanent rollback + # point, unlike the moving tag that student repositories follow. + docker build \ + -t "$IMAGE:${{ inputs.tag }}" \ + -t "$IMAGE:sha-${GITHUB_SHA::7}" \ + . + + - name: Push + run: | + docker push "$IMAGE:${{ inputs.tag }}" + docker push "$IMAGE:sha-${GITHUB_SHA::7}" + + - name: Summary + run: | + { + echo "### Published" + echo "" + echo "| Tag | Purpose |" + echo "|---|---|" + echo "| \`$IMAGE:${{ inputs.tag }}\` | Moving tag student repositories follow |" + echo "| \`$IMAGE:sha-${GITHUB_SHA::7}\` | Immutable, this commit |" + echo "| \`$IMAGE:${{ inputs.tag }}-previous\` | The image this run replaced |" + echo "" + echo "Roll back with:" + echo "" + echo '```' + echo "docker buildx imagetools create -t $IMAGE:${{ inputs.tag }} $IMAGE:${{ inputs.tag }}-previous" + echo '```' + } >> "$GITHUB_STEP_SUMMARY" diff --git a/CLAUDE.md b/CLAUDE.md index b1516878..5a94a823 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -101,7 +101,7 @@ dotnet test --filter "Name=SomeTestMethod" # single test method go build go test ./... -test.v ``` -Ships as a container (`Dockerfile`) published to `ghcr.io/akosdudas/ahk-publish-results-pr`, invoked as a GitHub Action step. `.devcontainer` is provided for development. +Ships as a container (`Dockerfile`) published to `ghcr.io/bmeaut/ahk-publish-results-pr` (moved out of a former employee's personal namespace; **student repos generated before the move still reference `ghcr.io/akosdudas/...`** and need their `uses:` line edited), invoked as a GitHub Action step. `.devcontainer` is provided for development. ### ahk-backend (.NET 10) ```bash diff --git a/README.md b/README.md index a923472c..dfbb3cd2 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The four applications below remain deployed for courses that have not migrated y **[GitHub Monitor](./github-monitor)**: An Azure function written in .NET with an http webhook registered as a GitHub Application that manages the workflow of homework submissions. Performs automatic actions on repositories acting as submissions and monitors proper usage of pull requests. -**[Publish Results to PR](./publish-results-pr)**: A [containerized](https://github.com/users/akosdudas/packages/container/package/ahk-publish-results-pr) Go application that processes the output of evaluator applications and publishes the results into a pull request for the student to see, as well as forwarding it to the _grade management_ application. +**[Publish Results to PR](./publish-results-pr)**: A [containerized](https://github.com/orgs/bmeaut/packages/container/package/ahk-publish-results-pr) Go application that processes the output of evaluator applications and publishes the results into a pull request for the student to see, as well as forwarding it to the _grade management_ application. **[Grade Management](./grade-management)**: An Azure function written in .NET that accepts events from the other applications and stores them in Azure CosmosDB database. Helps teachers by reducing the administration of tracking the status of submissions and exporting final grades. diff --git a/ahk-backend/docs/github-app.md b/ahk-backend/docs/github-app.md index e32fd056..f17f9a71 100644 --- a/ahk-backend/docs/github-app.md +++ b/ahk-backend/docs/github-app.md @@ -66,7 +66,7 @@ made itself. The health check reports this as a warning before it happens. ## Permissions -Set these under **Repository permissions**. Organization permissions are not needed at all. +Set these under **Repository permissions**, plus the one **Organization permission** below. | Permission | Level | Why | |---|---|---| @@ -77,6 +77,12 @@ Set these under **Repository permissions**. Organization permissions are not nee | Issues | Read & write | Issue comments carry the `/ahk ok` chatops and every warning the rules post. | | Actions | Read-only | Counting workflow runs against the course's threshold. | +Under **Organization permissions**: + +| Permission | Level | Why | +|---|---|---| +| **Members** | Read-only | `GET /orgs/{org}/members/{login}` is how the portal decides who may grade. **`/ahk ok` is refused for everyone without this**, and the workflow-run rule cannot tell staff from students, so it warns staff too. | + Note that **Administration: write is broad** — it also permits changing repository settings and deleting repositories. There is no narrower permission that covers creating repositories and adding collaborators, so this is the floor, not a choice. @@ -197,6 +203,10 @@ Specific failures: - **“limited to selected repositories”** — change the installation's repository access to *All repositories*. - **Student says the repository 404s** — they almost certainly have an unaccepted invitation. Point them at `/my` on the portal. +- **`/ahk ok` answers "@you is not allowed to do that"**, even for an organization **owner** — the portal asks GitHub whether the commenting login is a member of the organization that owns the repository, and got "no". Usually this is a *visibility* problem rather than a membership one: an App installation is not itself an organization member, so without **Organization → Members: Read** GitHub answers as it would for any outsider and only confirms **public** memberships. Anyone whose membership is *Private* (GitHub's default) then reads as a non-member. + Grant the App **Members: Read** and have an owner **approve** the added permission on the installation page. To confirm the diagnosis in seconds without touching the App, set your own membership to Public at `https://github.com/orgs//people` and try again. + Other causes, if that is not it: the person really is an **outside collaborator** rather than a member (commenting on a pull request does not imply membership); or the repository lives under a *user* account rather than an organization, in which case grading can never be authorized. + ⚠️ The answer is cached for **one hour** per org+login. After any of these fixes, restart the application to flush it rather than waiting. - **Every delivery is `405` with `Allow: GET, HEAD`** — the webhook URL points at the portal but not at `/api/integrations/github`. The request fell through to the Angular single-page app's fallback route, which only answers GET. Check the path, including that it has no trailing slash. diff --git a/publish-results-pr/README.md b/publish-results-pr/README.md index fdf6cbd0..1c7a4bb4 100644 --- a/publish-results-pr/README.md +++ b/publish-results-pr/README.md @@ -26,7 +26,11 @@ The extension of image files (with leading dot). When specified, the images are #### `AHK_APPURL` -The URL of the _grade management_ application's webhook accepting the results for storing in a database. If not specified, publishing the data to the webhook is disabled. +The URL of the webhook accepting the results for storing in a database — today `https://ahk.aut.bme.hu/api/integrations/evaluation-result` (see `ahk-backend/docs/ci-callback.md`). + +⚠️ **Unlike the two settings below, omitting this does not disable publishing.** When the input is absent the application falls back to a built-in default URL, so a workflow that leaves it out silently posts to whatever that default happens to be. Setting it to an empty string *does* disable publishing, because publishing requires all three of URL, token and secret to be non-empty. + +⚠️ The URL is part of the request signature, so it must match the receiving endpoint byte for byte — `https`, no trailing slash. Case is the only forgiving part. #### `AHK_APPTOKEN` @@ -52,7 +56,7 @@ jobs: run: do-eval.sh - name: Publish results - uses: docker://ghcr.io/akosdudas/ahk-publish-results-pr:v1 + uses: docker://ghcr.io/bmeaut/ahk-publish-results-pr:v1 with: AHK_RESULTFILE: "result.txt" AHK_IMAGEEXT: ".png"
+
+
+ Courses / {{ c.slug }} +

{{ c.name }}

+

+ {{ c.studentCount }} students, {{ c.submissionCount }} submissions. Created + {{ c.createdAt | date: 'longDate' }}. +

+
+ +
+ + @if (error(); as e) { +

{{ e }}

+ } + @if (saved(); as s) { +

{{ s }}

+ } + + +
+
+
+

Integration health

+

Checked against the settings below, and against GitHub itself for the access token.

+
+ +
+
+ @if (report(); as r) { + + } @else if (checking()) { +

Running checks…

+ } @else { +

The checks could not be run.

+ } +
+
+ + +
+
+
+
+

Course settings

+

How this course is identified, and which repositories belong to it.

+
+
+
+
+
+ + + @if (slugChanged()) { + + Changing the slug changes every URL for this course. Existing links will stop working. + + } @else { + Used in the address: /{{ c.slug }}/dashboard + } +
+
+ + +
+
+
+
+ + + Deliveries from this organization are routed to this course. +
+
+ + + Only needed when one organization hosts several courses. +
+
+
+
+ +
+
+
+ + +
+
+
+
+

GitHub integration

+

Credentials this course uses to talk to GitHub. Stored values are never shown again.

+
+
+
+
+
+ + +
+
+ + + Runs a student may trigger per repository before the monitor steps in. +
+
+ +
+ + + + @if (c.gitHubConfig?.hasAccessToken) { + A token ending …{{ c.gitHubConfig?.accessTokenHint }} is stored. + + } @else { + Needs the read:org and repo scopes. This is the token the health check verifies. + } + +
+ +
+ + + + @if (c.gitHubConfig?.hasWebhookSecret) { + A secret is stored. + + } @else { + Validates the X-Hub-Signature-256 header on incoming deliveries. + } + +
+ +
+ + + + @if (c.gitHubConfig?.hasAppPrivateKey) { + A private key is stored. + + } @else { + Used to authenticate as the GitHub App installation for this course. + } + +
+ + +
+
+ + @if (c.gitHubConfig?.updatedAt) { + Last changed {{ c.gitHubConfig?.updatedAt | date: 'medium' }} + } +
+
+
+ + +
+
+
+

CI callback tokens

+

The evaluator workflow signs its results with one of these. Revoke a token to cut it off.

+
+
+ + @if (issuedToken(); as t) { +
+

Token created. Copy the secret now — it is not shown again.

+
+
Token
+
{{ t.token }}
+
Secret
+
{{ t.secret }}
+
+ +
+ } + +
+ + + + + + + + + + + + @for (t of c.webhookTokens; track t.id) { + + + + + + + + } @empty { + + + + } + +
TokenDescriptionCreatedState
{{ t.token }}{{ t.description || '—' }}{{ t.createdAt | date: 'yyyy-MM-dd' }} + @if (t.revokedAt) { + Revoked {{ t.revokedAt | date: 'yyyy-MM-dd' }} + } @else { + Active + } + + @if (!t.revokedAt) { + + } +
+ No tokens yet. Evaluation results cannot be accepted until one exists. +
+
+ +
+ + +
+
+ + +
+
+
+

Staff

+

Who can open this course. Site admins can open it regardless of this list.

+
+
+ +
+ + + + + + + + + + + @for (m of c.members; track m.userId) { + + + + + + + } @empty { + + + + } + +
UserEmailRole in course
+ {{ m.userName }} + @if (m.displayName) { +
{{ m.displayName }}
+ } +
{{ m.email || '—' }} + + + +
No staff assigned yet.
+
+ +
+
+ + @if (searching()) { + Searching… + } +
+ + @if (candidates().length > 0) { +
    + @for (u of candidates(); track u.id) { +
  • + {{ u.userName }} + {{ u.displayName || u.email || '—' }} + + @if (isMember(u)) { + Already staff + } @else { + + + } +
  • + } +
+ } @else if (memberSearch.trim().length >= 2 && !searching()) { +

No user matches "{{ memberSearch }}".

+ } +
+
+ + +
+
+
+

Delete this course

+

+ Removes the course and everything assigned to it: students, submissions, events, grades, tokens and + staff assignments. This cannot be undone. +

+
+
+
+ + +
+
+