Commit Graph

81 Commits

Author SHA1 Message Date
HolgerHatGarKeineNode f5cf85b438 Add restore_point functionality to Meetups
- 💾 Introduced `restore_point` JSON column in `meetups` table for saving and restoring master data.
- 🛠️ Added methods `captureRestorePoint` and `restoreFromRestorePoint` to `Meetup` model for managing restore points.
- 🔒 Implemented authorization for updating meetups via `updateViaPortal` policy to include pivot members.
- 🔗 Created Artisan commands `meetups:snapshot` and `meetups:restore` for managing restore points from CLI.
- 🚦 Added rate limiter to restrict excessive update attempts in Livewire meetup editing.
-  Developed exhaustive feature tests for snapshot and restore actions, portal editing rules, and rate limiting.
2026-06-10 10:56:38 +02:00
HolgerHatGarKeineNode 8c68b19138 Add Super-Admin tools for managing any model
- 🛠️ Introduced generic Super-Admin MCP tools, including `list-models`, `describe-model`, `list-records`, `show-record`, `create-record`, and `update-record`.
- 🛡️ Restricted modification of critical fields (e.g., passwords, roles, tokens) to enhance security.
-  Added extensive feature tests for Super-Admin functionality and access control.
- 📜 Increased pagination length to accommodate new tools on a single page.
- 🔗 Registered Super-Admin tools in `EinundzwanzigServer`.
2026-06-08 13:39:04 +02:00
HolgerHatGarKeineNode 3a507cced2 Enhance meetup association and permissions management
- 🔍 Added `resolveInScope` method to `ResolvesEntities` for scoped entity resolution with stricter control.
- 👥 Introduced `AddMeetupToMineTool` MCP tool for adding external meetups to "My Meetups."
- 🛠️ Updated `ListMyMeetupsTool` and `ShowMyMeetupTool` to include both created and joined meetups.
- 📚 Updated `Meetup` model with `associatedWith` scope for querying user-related meetups.
-  Expanded feature tests for meetup membership, creator permissions, and scoped tool usage.
- 🛡️ Unified access checks across Livewire and APIs to restrict editing meetup details to creators or super-admins.
- 🔗 Registered `AddMeetupToMineTool` in `EinundzwanzigServer`.
2026-06-08 11:59:02 +02:00
HolgerHatGarKeineNode dc2b828777 Add SearchMeetupsTool for duplication prevention
- 🔍 Introduced `SearchMeetupsTool` to find existing meetups by name or city before creating new ones.
- ☑️ Updated `CreateMeetupTool` description and logic to enforce pre-checks for existing meetups.
- 🛠️ Adjusted `EinundzwanzigServer` to include `SearchMeetupsTool` in tools list.
-  Added feature tests to verify meetup search functionality and ensure duplication avoidance.
2026-06-08 11:10:29 +02:00
HolgerHatGarKeineNode ab8b91a0af Ensure all tools fit on a single tools/list page
- 📜 Increased `defaultPaginationLength` to 100 to accommodate all tools on a single page.
-  Added feature test to confirm pagination settings align with client requirements.
2026-06-08 10:54:18 +02:00
HolgerHatGarKeineNode b6f05bca41 Add ResolvesEntities concern for name-based ID resolution
- 🤖 Introduced `ResolvesEntities` trait to simplify entity resolution by name or ID across MCP tools.
- 📚 Updated tools (Meetups, Cities, Venues, Courses, Lecturers) to use the concern for resolving related entities (e.g., courses, venues, lecturers).
- 🎯 Enhanced tool descriptions and schemas for better name-based parameter handling with fallback support for IDs.
-  Added dedicated feature tests for name resolution logic, partial matches, and error handling scenarios.
2026-06-08 10:35:16 +02:00
HolgerHatGarKeineNode d0544bfac9 Add OAuth functionality, MCP tools, and feature tests
- 🔒 Added migrations for `oauth_access_tokens`, `oauth_refresh_tokens`, `oauth_auth_codes`, `oauth_clients`, and `oauth_device_codes`.
- 🤖 Created MCP tools (Meetups, Cities, Venues, Courses, Lecturers) for managing entities with authentication and validation.
- 🛠️ Implemented Passport-backed OAuth API guard configuration and validation endpoints.
-  Added comprehensive feature tests for MCP tools and OAuth functionality (access control, validation, and token-based authentication).
2026-06-08 09:37:00 +02:00
HolgerHatGarKeineNode 3cad5f5636 **Enhance input validation and error handling across APIs**
- 🛠️ Refactored controllers to utilize `FiltersNumericIds` concern, ensuring secure numeric ID filtering and avoiding type-sensitive errors in queries.
-  Added feature tests to validate robust input hardening for non-numeric or malformed query parameters (`user_id`, `selected[]`).
- 🔒 Introduced `PublicPropertyNotFoundException` handling in Livewire, returning 400 for invalid property probes and suppressing unnecessary log entries.
-  Updated `MeetupEventController` to handle invalid date formats gracefully, aborting with a 400 response instead of 500.
-  Expanded exception handling pipeline for enhanced resilience against malformed input, bot noise, and exploitable probes.
2026-06-08 02:53:44 +02:00
HolgerHatGarKeineNode 3b93e22e95 **Add authenticated API endpoints for managing Meetups, Cities, Venues, and Lecturers**
-  Introduced `store`, `update`, `mine`, and `mineShow` endpoints for `Meetups`, `Cities`, `Venues`, and `Lecturers` with validation and authorization.
- 🔒 Added `Policies` for `Meetups`, `Cities`, `Venues`, and `Lecturers` leveraging `ChecksCreatorOwnership` for ownership checks.
- 🌐 Created `Resources` for structured API responses: `MeetupResource`, `CityResource`, `VenueResource`, and `LecturerResource`.
-  Added dedicated `Request` classes for input validation: `Store` and `Update` variants for all models.
- 🛠️ Updated controllers to support new functionalities with localized error messages and proper HTTP responses.
2026-06-08 01:58:37 +02:00
HolgerHatGarKeineNode 7510946f38 **Add public API documentation access and navigation links**
- 📚 Added "API Dokumentation" link to the sidebar and header navigation.
- 🔓 Defined `viewApiDocs` gate for public access to API documentation.
-  Added feature tests for API documentation route accessibility and OpenAPI document serving.
2026-06-08 01:34:00 +02:00
HolgerHatGarKeineNode 3875e127e4 🔥 **Remove Highscore and Bindle features**
- 🗑️ Deleted `Highscore` feature (Model, Controller, Factory, Tests, Routes, Migrations) and associated logic.
- 🗑️ Removed `BindleController` and its related test.
- 🧹 Cleaned up unused routes, database seeders, and localization references.
- 🚫 Deprecated inactive book rental guide component and associated views.
2026-06-08 01:08:07 +02:00
HolgerHatGarKeineNode 351dd87fa9 **Enhance API functionality and localizations**
- 🌐 Added API documentation annotations for multiple controllers (Meetups, Cities, Countries, Courses, Highscores, Venues), improving public and developer-facing endpoint clarity.
-  Integrated and configured the `dedoc/scramble` package for automated OpenAPI documentation generation.
- 🔒 Excluded internal routes and actions from API documentation using `ExcludeRouteFromDocs` attributes.
- 🌍 Added new localization keys for API Token features across multiple languages (`lv`, `es`, etc.).
- 🛠️ Introduced `Group`, `Response`, and `QueryParameter` attributes for better request descriptions and structured documentation.
- 🚀 Enhanced functionality for listing operations in controllers with filters and query parameters like `search` and `selected`.
2026-06-08 00:09:59 +02:00
HolgerHatGarKeineNode 4c81e20529 feat(settings): API token management UI for users
Adds a "API Tokens" settings page so an authenticated user can create and
revoke Sanctum personal access tokens for the new authenticated write
endpoints — using the official Sanctum API ($user->createToken() / tokens()).

- New Volt component settings/api-tokens (create token, one-time plain-text
  reveal with copy-to-clipboard, list + revoke own tokens).
- Registered route settings.api-tokens (country-prefixed, auth group) and
  added a nav entry in the settings layout.
- SEO definition for the new page.
- Pest feature tests (create/reveal-once, validation, revoke, ownership
  scoping) and a Pest browser screenshot test.
2026-06-07 22:56:28 +02:00
HolgerHatGarKeineNode a3062f6c4e feat(api): authenticated course & course-event write endpoints
Implements Sanctum-authenticated write endpoints so a lecturer can create
and update their own courses and dated course events programmatically
(e.g. to keep the portal's course events in sync with an external system).

- CourseController@store / @update implemented (validation mirrors the
  Livewire course create form; create requires is_lecturer, update is
  restricted to the owner or a super-admin).
- New CourseEventController with index/store/update. index returns only the
  authenticated user's own events (optional ?course_id= filter) for
  idempotent syncing; validation mirrors the Livewire course event form.
- Public `courses` API resource narrowed to index/show; all writes moved
  behind an `auth:sanctum` route group (the previous store/update/destroy
  actions were empty no-ops).
- Pest feature test covering auth (401), authorization (403/is_lecturer/
  ownership), creation (201), validation (422) and ownership-scoped listing.

Ported from Einundzwanzig-Podcast/einundzwanzig-portal#25, adapted to this
repo's conventions (inline authorization instead of policies, Pest tests,
validation mirroring the current Livewire forms) while keeping the same
endpoint outputs.

Co-authored-by: schnuartz-ai <schnuartz@gmail.com>
2026-06-07 22:14:29 +02:00
HolgerHatGarKeineNode 3a8775fa52 🛡️ **Add robust Livewire payload validation and throttling**
-  Implemented handling for `CorruptComponentPayloadException` to prevent logging noise and improve exception management.
- 🛠️ Added IP-based throttling (120 requests/min) for the `/livewire/update` endpoint with middleware integration for better traffic control.
-  Introduced unit tests to validate throttle settings and middleware application.
- 🧪 Enhanced tests for ensuring silent handling of corrupt payload scenarios and reduced log noise.
2026-06-04 11:45:02 +02:00
HolgerHatGarKeineNode 35ddad365c **Add Latvian translations and enhance localization support**
-  Added Latvian (`lv`) JSON translations and validation/password localization files.
- 🛠️ Updated `lang-country` config to include `lv-LV` and centralized language definitions.
- 🌐 Extended sidebar and navigation with new translatable strings.
-  Introduced 72px width customization for the sidebar layout.
-  Improved timezone mapping in Nostr publishing commands (added `Europe/Riga`).
- 🛠️ Refactored language selector to dynamically source available languages from the config.
2026-05-20 11:45:50 +02:00
HolgerHatGarKeineNode 308cd8a611 🚀 **Automate Meetup Activity Recalculation**
- Introduced `recalculateActivity` method in `Meetup` model to centralize activity and event timestamp updates.
- Added `MeetupEventObserver` to trigger activity recalculation on event save/delete.
- Updated `/meetups:update-activity` command to leverage the new model method for cleanup.
- Enhanced tests to cover various `MeetupEvent` scenarios affecting activity states.
2026-05-17 18:13:37 +02:00
HolgerHatGarKeineNode 71a4898303 🎉 **Introduce meetup activity management**
- Added `is_active` and `last_event_at` fields to meetups with migration.
- Enhanced UI: Display `Aktiv`/`Inaktiv` badges and last event dates across dashboard, tables, and maps.
- Introduced `/meetups:update-activity` command to manage activity flags and timestamps.
- Validated latitude/longitude to prevent `0,0` inputs in city creation and updates.
- Updated factories and tests to include meetup activity states (`active`, `inactive`).
2026-05-17 17:57:16 +02:00
HolgerHatGarKeineNode 52276ee682 🗑️ **Remove redundant Laravel Boost guidelines**
Deleted unused Laravel Boost guideline files (`laravel-boost.md` and `laravel-boost.mdc`) to clean up the repository.
2026-05-17 15:08:01 +02:00
Claude d46c0161fe security: medium-severity fixes (proxies, ssrf, uploads, lnurl, github_data)
- Trust the Forge reverse proxy and force https URLs in production so
  generated absolute URLs match the actual TLS termination.
- Reject Nostr profile photo URLs that aren't http(s) or that resolve to
  loopback / private (RFC1918) addresses to close an SSRF vector in
  FetchNostrProfileJob.
- Tighten image upload validation across meetup, course, and lecturer
  create/edit components: explicit mimes whitelist (jpeg, png, webp),
  max 5 MiB, and dimension cap of 4000x4000.
- Replace the silent "skip if exists" branch in LnurlAuthController with
  updateOrCreate so concurrent callers cannot race on the k1 record.
- Validate github_data on Meetup edit, decoding the JSON, and keep only
  the whitelisted keys (top, left, state) with strict type coercion to
  prevent storing arbitrary attacker-controlled JSON.
2026-05-03 12:57:57 +00:00
Claude 9b81f6cd92 security: high-severity fixes (api throttle, fillable, idor, path, rel)
- Add 60 req/min throttle to the public API group and a stricter 10 req/min
  throttle to POST /highscores.
- Replace mass-assigned $guarded=[] with explicit $fillable on User, Meetup,
  Course, Lecturer, and SelfHostedService. created_by stays out of the
  whitelist; the existing creating() hooks continue to populate it.
- Require authenticated user on Api/MeetupController::index instead of
  trusting the user_id query parameter (IDOR).
- Constrain the /img and /img-public route paths to a safe character set
  and reject any path containing ".." in ImageController.
- Add rel="noopener noreferrer" to every target="_blank" link on the meetup
  and course landing pages.
2026-05-03 12:55:09 +00:00
Claude 90835f8b1f security: critical fixes (test route, edit authz, nostr signature, calendar IDOR)
- Remove unauthenticated /test route that dispatched FetchNostrProfileJob
  for a hardcoded user (routes/web.php).
- Enforce created_by ownership check in meetup and lecturer Livewire edit
  components; mirror the existing services/edit pattern.
- Replace blind-trust nostrLoggedIn handler with NIP-42-style signed event
  verification: server-issued challenge stored in session, client signs a
  kind:22242 event, server verifies signature via swentel/nostr-php and
  derives npub. Challenge is single-use with 5-minute TTL.
- Validate the ?my[] parameter on the calendar download endpoint as an
  array of integers and intersect with the authenticated user's meetups.
2026-05-03 12:51:10 +00:00
BT 04e3e30fcf 🔥 **Cleanup:** Removed BookCase and OrangePill models, factories, migrations, and related references. Added tests for new service and meetup creation flows. Updated PHPUnit settings and browser-specific configurations. 2026-05-02 22:00:26 +01:00
BT 1f0bfba0d3 🎨 **Style:** Fixed indentation inconsistencies in meetup_user migration file.
🛠️ **Factory:** Created factories for `TwitterAccount`, `EmailCampaign`, `EmailTexts`, and `BookCase`.
 **Helper:** Added `NostrHelper` with methods for generating fake/mocked Nostr data.
⬆️ **Dependencies:** Updated multiple Composer dependencies including `laravel/framework`, `astrotomic/laravel-translatable`, and others to their latest versions.
2026-05-02 19:17:02 +01:00
HolgerHatGarKeineNode 2f5ca24da0 🔥 Remove Laravel Sail, Docker, and related setup, migrate to simplified local development environment
- **Removed:** `docker-compose.yml`, Sail-specific Dockerfiles, and related scripts for PHP 8.3 setup.
- **Updated:** Documentation to reflect a shift from Docker to a direct PHP-based local development workflow.
- **Removed:** `laravel/sail` dependency from `composer.lock`.
- **Implemented:** `#[Locked]` Livewire attribute across components for read-only properties.
- **Added:** Feature tests to ensure locked properties cannot be tampered with.
2026-02-11 21:10:09 +01:00
HolgerHatGarKeineNode bb84117fd1 🛠️ Remove deprecated Forge deployment workflow, add logic for fetching missing highscore names via Nostr, and update API routes with refined highscore endpoints. 2026-02-02 12:36:00 +01:00
HolgerHatGarKeineNode 6dd04dee30 🏆 Add highscore feature with API endpoints, validations, and tests
- **Added:** Endpoints for submitting highscores (`highscores.store`) and retrieving the leaderboard (`highscores.index`).
- **Implemented:** Validation rules via `StoreHighscoreRequest` to ensure highscore integrity.
- **Included:** `Highscore` model, migration, and factory for data handling and seeding.
- **Enhanced:** Comprehensive feature tests covering submission, updating, retrieval, and payload validation.
2026-02-02 12:27:01 +01:00
HolgerHatGarKeineNode 32e327cd9c 🔥 Remove redundant PRD.md file, update media models with stricter MIME type validation, and refine media conversion settings. 2026-01-25 23:54:44 +01:00
HolgerHatGarKeineNode da1324adda 🗓️ Add MeetupEventFactory, implement rate limiting for calendar downloads, and enhance test coverage
- **Added:** `MeetupEventFactory` for generating test data.
- **Implemented:** Rate limiting (`throttle:calendar`) for `stream-calendar` routes to prevent abuse.
- **Enhanced:** `DownloadMeetupCalendar` controller with validation and cleaner query structure.
- **Added:** Feature tests for calendar downloading, invalid input handling, and rate limiting.
2026-01-17 21:18:55 +01:00
HolgerHatGarKeineNode 7f92e77684 🔥 Remove unused tests, update factories, and introduce recurrence features
- **Removed:** Unused feature and component tests to clean up the codebase.
- **Added:** `RecurrenceType` enum for handling event recurrence modes.
- **Introduced:** City, Country, and Meetup factories for test data generation.
- **Implemented:** Migration to support recurring event fields in `meetup_events` table.
- **Enhanced:** Livewire meetup events creation with recurrence validation and preview logic.
- **Updated:** PHPUnit test suite configuration and composer dependencies for `pestphp/pest@v4.3`.
- **Refined:** SEO configuration (`favicon`) to standardize icon format.
2026-01-17 21:00:46 +01:00
HolgerHatGarKeineNode 74263a4581 🔒 Add manual hex validation for LNURL-Auth parameters k1 and key with improved test coverage 2026-01-17 17:25:21 +01:00
HolgerHatGarKeineNode e5ea65fa77 🔑 Implement LNURL-Auth support with error handling, frontend polling, and test coverage
- Added `LnurlAuthController` to handle LNURL authentication flow with signature verification, user creation, and session expiry checks.
- Integrated authentication error polling in `nostrLogin.js`.
- Added `LoginKeyFactory` for testing and database seed purposes.
- Created feature tests (`LnurlAuthTest`) to validate LNURL callback, error responses, and session handling.
- Extended `login.blade.php` with dynamic error handling and reset logic for expired sessions.
2026-01-17 15:23:38 +01:00
HolgerHatGarKeineNode 233402dace 🔧 Add .gitignore for static assets and update comment language in DomainMiddleware 2025-12-14 20:53:09 +01:00
HolgerHatGarKeineNode 1ccbd0a9ed 🔄 Refactor domain image helper to return attributes array
🖼️ Update SEO data to use domain attributes instead of single image
🌐 Adjust meetup model and blade component to use new domain attributes function
2025-12-11 16:35:46 +01:00
HolgerHatGarKeineNode deeb1f066d 🌍 Update timezone fallback for Nostr publishing command to use Europe/Berlin 2025-12-11 02:13:17 +01:00
HolgerHatGarKeineNode a8f1257948 🌍 Add Austria and Switzerland to German locale mapping in Nostr publishing command
- Extend `TZ_MAP` and `DOMAIN_MAP` with `'at'` and `'ch'` entries pointing to `Europe/Berlin` and `portal.einundzwanzig.space` respectively.
- Adjust locale setting logic to use `'de'` for Austria and Switzerland, ensuring consistent language handling in Nostr publishing flows.
2025-12-10 03:46:14 +01:00
HolgerHatGarKeineNode 52c05e6d47 ⚙️ Preserve user language preference in DomainMiddleware and adjust locale‑setting logic to avoid overwriting existing session values while still configuring domain‑specific app settings. 2025-12-09 23:41:44 +01:00
HolgerHatGarKeineNode c6c524a876 ⚙️ Update PublishUnpublishedItems to run hourly and only publish MeetupEvents starting within the next 7 days. 2025-12-09 23:02:43 +01:00
HolgerHatGarKeineNode d263eaf92d 🛠️ Add German portal domain and refactor URL handling for Nostr publishing
- Introduce `portal.einundzwanzig.space` with locale settings in `DomainMiddleware`.
- Replace verbose if‑chain in `NostrTrait::getUrl()` with a concise match expression.
- Add `DOMAIN_MAP` constant to `PublishUnpublishedItems` and force URL generation to use the correct domain per country.
- Update command flow: set domain before configuring timezone/locale.
2025-12-09 22:45:26 +01:00
HolgerHatGarKeineNode 2a70537fcb 🛠️ Add Nostr publishing support with i18n templates and country‑specific configuration for domain handling and CLI command 2025-12-09 22:35:54 +01:00
HolgerHatGarKeineNode c4cea2ae7a 🛠️ Add anon column to self-hosted services: Update views, models, forms, and migrations to support anonymous service creation and display 2025-12-07 06:16:47 +01:00
HolgerHatGarKeineNode 980b833e80 🌐 Enhance service management: Add IP address field to forms, views, and database schema 2025-12-07 06:04:52 +01:00
HolgerHatGarKeineNode 4e150518a4 🛠️ Remove deprecated LNbits enum and related references from SelfHostedServiceType 2025-12-07 05:18:54 +01:00
HolgerHatGarKeineNode 14f717a2b9 🛠️ Refactor service components: Add dynamic type filters, restructure landing page UI, and introduce ServiceForm for improved form handling and validations 2025-12-07 01:06:20 +01:00
HolgerHatGarKeineNode aef4deedd6 🛠️ Add services index and landing page components with dynamic links and new Polish translations 2025-12-07 00:01:15 +01:00
HolgerHatGarKeineNode d0d19663aa 🛠️ Ensure meetup names are converted to ASCII before sanitizing in ExtractLogos command 2025-12-05 23:27:12 +01:00
HolgerHatGarKeineNode 22592bbd23 🛠️ Use sanitized studly case for meetup names in ExtractLogos command output filenames 2025-12-05 23:07:28 +01:00
HolgerHatGarKeineNode 60634146fe 🛠️ Use camel case for meetup names in ExtractLogos command output filenames 2025-12-05 23:02:10 +01:00
HolgerHatGarKeineNode 1adbec3519 🛠️ Add ExtractLogos command to export meetup logos to public storage 2025-12-05 22:54:17 +01:00
HolgerHatGarKeineNode 6f77108ca2 🌐 Add Polish translations and expand Spanish dictionaries
- Added a new `lang/pl.json` file with comprehensive Polish translations.
- Enhanced `lang/es.json` with additional Spanish keys and phrases for better coverage.
2025-12-02 19:56:35 +01:00