Commit Graph

242 Commits

Author SHA1 Message Date
HolgerHatGarKeineNode 7e491326a9 Build the Nostr signer URI in the browser, not server-side
Server-side percent-encoding (rawurlencode/http_build_query) produced a
nostrsigner: URI that Amber rejected as malformed. The launcher view now
assembles it in JS with encodeURIComponent(JSON.stringify(event)) — the
exact encoding Amber accepts (verified working earlier in the session).
The controller only passes k1 and the callback URL.
2026-06-11 22:40:57 +02:00
HolgerHatGarKeineNode 58c7e410b0 Add headless Nostr launcher page for the mobile app
A direct ACTION_VIEW intent to nostrsigner: (Browser::open from the app)
lacks category.BROWSABLE, so Amber routes it into its app-to-app path
and rejects it as malformed. The app instead opens /auth/mobile/nostr in
an in-app browser; that page fires the signer via window.location, so
the intent carries BROWSABLE and Amber uses its web-signing flow. No
visible login UI, local signing, token returned via the App Link.
2026-06-11 22:08:17 +02:00
HolgerHatGarKeineNode 64a5fcd9f1 Make the mobile login page Lightning-only
The Nostr login is now driven entirely by the app (it launches the
NIP-55 signer via an ACTION_VIEW intent and posts the signed event to
/auth/mobile/signed), so the portal page no longer needs window.nostr or
an Amber button — it only renders the Lightning QR. The path-based
signer callback and token exchange endpoints remain server-side.
2026-06-11 21:51:01 +02:00
HolgerHatGarKeineNode c30f1932e4 Use window.nostr (NIP-46/Amber bunker) on the mobile login page
Replaces the fragile NIP-55 intent/callback round-trip with the same
mechanism the desktop login uses: openNostrLogin signs the session
challenge via window.nostr — provided by an extension or by
window.nostr.js over a persistent NIP-46 connection (Amber pairing with
permissions). The listener stores a LoginKey for the page's k1 and
navigates to the completion route, which issues the token and redirects
into the app via the verified App Link handoff.
2026-06-11 20:47:02 +02:00
HolgerHatGarKeineNode 7531f28f22 Add verified App Link handoff and mobile token exchange endpoint
Replaces the custom-scheme auto-redirect (which triggers Chrome's
confirmation prompt) with a verified Android App Link handoff:

- public/.well-known/assetlinks.json for space.einundzwanzig.mobile
  (debug cert fingerprint; add the release cert before store builds)
- GET /app/auth handoff: opens the app directly when the App Link is
  verified; renders a button-based fallback page otherwise
- POST /api/mobile/token: trades a NIP-55-signed login event for a
  Sanctum token — used when Amber's callback opens the app directly
- complete/confirm/signedCallback now redirect to the handoff URL
2026-06-11 19:51:14 +02:00
HolgerHatGarKeineNode 4aba1514e9 Make the NIP-55 signer callback robust against Amber URL rewriting
Amber drops the query string when it rebuilds the callback URL and
appends the signed event directly to the path. The mobile login page now
hands out path-based callback URLs (/auth/mobile/signed/{k1}/) so the
event arrives as the remainder of the path.

The new callback runs in the web middleware group: the signer opens it
in the system browser, which shares cookies with the in-app browser
session, so the flow completes immediately — a bridge page issues the
token and fires the einundzwanzig:// deep link. The LoginKey row is
still written as a fallback for the polling login page.
2026-06-11 18:43:59 +02:00
HolgerHatGarKeineNode 07169dfee6 Add mobile app auth flow with Sanctum token handoff via deep link
The Einundzwanzig mobile app opens /auth/mobile in an in-app browser.
After a Lightning (LNURL) or Nostr login the flow issues a personal
access token and hands it back via the einundzwanzig://auth deep link.

- New auth.mobile-login Livewire view: Lightning QR (shared k1) plus
  Nostr signing via NIP-55 Android signers (Amber) with server callback,
  and a confirmation screen for already authenticated sessions
- MobileAuthController: NIP-55 callback verification, completion route
  issuing the token (replacing same-device tokens), redirect whitelist
- Nostr login event verification and npub user resolution extracted to
  App\Support\NostrLogin, now shared with the interactive login
- GET /api/user (auth:sanctum) returns the token owner's profile
2026-06-11 18:01:50 +02:00
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 dc05299e5a 🎨 Implement dark mode styles for authorization view 2026-06-08 09:48:26 +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 d1b7352fca 🛠️ **Fix config serialization and optimize caching**
- 🗑️ Removed `SecurityScheme` from `scramble.php` due to non-serializable issues causing `config:cache`/`optimize` failures.
- ✏️ Added clarification on `scheme` omission with default fallback to `SecurityScheme::http('bearer')`.
2026-06-08 01:13:23 +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
The Ben 5a325b1b28 Merge pull request #2 from HolgerHatGarKeineNode/feature/api-course-event-write-endpoints
feat(api): authenticated course & course-event write endpoints
2026-06-07 21:26:07 +00:00
HolgerHatGarKeineNode 08e42ad42c docs(media): add API token settings screenshot for PR 2026-06-07 22:56:39 +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 256f677fe0 🐛 **Handle Livewire exploit probes gracefully**
-  Added detection for Livewire exploit probes (`DirectlyCallingLifecycleHooksNotAllowedException` and magic method `MethodNotFoundException`) to prevent 500 errors.
- 🛠️ Updated exception handling to return a 400 response for probe requests.
- 🔇 Suppressed logging of exploit probe exceptions to reduce noise.
-  Added tests to verify 400 responses, logging suppression, and correct handling of legitimate exceptions.
2026-06-02 18:27:54 +02:00
HolgerHatGarKeineNode 51680c70e4 ⬆️ **Update dependencies in composer.lock**
Upgraded several dependencies:
- `guzzlehttp` to 7.11.0
- `laravel/framework` to v13.13.0
- `laravel/horizon` to v5.47.1
- Other minor updates including `livewire`, `psysh`, `symfony` components, and `spatie/laravel-medialibrary`.

Ensured compatibility and added updated packages with enhanced configurations.
2026-06-02 18:00:08 +02:00
HolgerHatGarKeineNode e05ee8965d **Add tests for LangCountry data resolution and Latvian overrides**
-  Introduced `LangCountryDataAvailabilityTest` to validate data file availability and integrity for allowed `lang-country` codes.
- 🛠️ Added Latvian (`lv-LV`) override JSON file with localized settings and validation.
- 🧪 Verified graceful switching between `lang-country` sessions in tests.
2026-05-24 22:09:26 +02:00
HolgerHatGarKeineNode e244c14f55 🌐 **Add and enhance localizations for multiple languages**
-  Added and synced new translations across `pt`, `nl`, `de`, and `lv` language files.
- 🛠️ Fixed missing and duplicate strings in multilingual JSON files.
-  Standardized formatting and indentation of `validation.php` (Latvian).
2026-05-24 21:57:40 +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 e3f8c4c232 🐛 **Handle MissingFileUploadsTrait exceptions gracefully**
-  Added detection logic for `MissingFileUploadsTraitException` to prevent 500 errors.
- 🛠️ Updated exception handling to return a 400 response for these scenarios.
- 🔇 Suppressed logging of `MissingFileUploadsTraitException` to reduce noise.
-  Added tests to verify 400 responses and absence of log entries.
2026-05-20 10:54:12 +02:00
HolgerHatGarKeineNode 03aacdb8ff 🐛 **Handle stale compiled view exceptions gracefully**
-  Added detection logic to identify missing compiled view files and avoid 500 errors.
- 🛠️ Updated exception handling to return 503 with `Retry-After` for stale compiled views.
- 🔇 Prevented logging of stale compiled view exceptions to reduce noise.
-  Added tests to validate 503 responses, `Retry-After` headers, and logging suppression.
2026-05-20 00:42:13 +02:00
HolgerHatGarKeineNode 8a3f90fc3d 🐛 **Handle stale Livewire asset exceptions gracefully**
-  Added detection logic for stale Livewire asset patterns to avoid 500 errors.
- 🛠️ Updated exception handling to return 404 for stale asset requests.
- 🔇 Prevented logging of stale asset exceptions to avoid unnecessary noise.
-  Added tests to verify 404 responses and absence of log entries for stale asset scenarios.
2026-05-20 00:31:02 +02:00
HolgerHatGarKeineNode 1f574ae5c8 🔧 **Add .codegraph config & update dependencies**
-  Added `.codegraph/config.json` for file inclusion/exclusion in analytics.
- ⬆️ Bumped versions of `guzzlehttp`, `laravel/framework`, `laravel/horizon`, `shiki`, `nostr-tools`, and other dependencies in `composer.lock` and `yarn.lock`.
- 🖼️ Enhanced file upload validation and preview support by including `.avif` MIME type in `livewire` components and configuration.
-  Added tests to ensure `.avif` is supported across file upload forms.
2026-05-20 00:22:53 +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 bf9654de87 🔄 **Refactor and extend meetup membership-based authorization**
- Updated `authorizeAccess` to restrict `meetups.edit` views and updates to users in "My-Meetups".
- Attached creators to `meetup_user` pivot for default membership.
- Adjusted related tests to validate membership-based edit permissions.

📱 **Improve sidebar and mobile navigation accessibility**
- Added `aria-labels` to improve screen reader support for sidebar and mobile header elements.
- Updated desktop and mobile user menus alignment for consistency.

 **Enhance Lightning login flow**
- Introduced `lightningLoginInProgress` for smoother polling synchronization with the redirect flow.
- Updated logic to dispatch `lightning-login-ready` event instead of immediate redirect, avoiding race conditions.
2026-05-17 17:28:17 +02:00
HolgerHatGarKeineNode 9582880dbf 🔒 **Enforce authorization for meetup edit and update views**
Added `authorizeAccess` method to restrict access to the meetup's creator, ensuring proper authorization during view rendering and updates.
2026-05-17 15:12:49 +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
HolgerHatGarKeineNode 57b1b21c8f 🛠️ **Remove redundant authorization call in meetup update method**
Streamlined the update method by eliminating the unnecessary `authorizeAccess` invocation.
2026-05-05 10:00:31 +02:00
HolgerHatGarKeineNode 8b3005c63b 🛠️ **Remove unnecessary authorization logic from meetup edit view**
Simplified component by eliminating redundant `authorizeAccess` method.
2026-05-05 09:59:40 +02:00
BT e7d1a949e8 **Nostr Login:** Improved user feedback and accessibility for login flow.
- 🔄 Added `x-effect` to lock page scrolling during login progress.
- 🛡️ Disabled login button and added loading indicators when `nostrLoginInProgress`.
- 🖼️ Introduced full-viewport progress overlay with accessible attributes and transitions.
- 🌐 Updated translations for signing states and instructions.
2026-05-04 00:43:50 +02:00
BT 686be7e8f7 **Nostr Login:** Prevented session race conditions during login flow.
- 🛡️ Added `nostrLoginInProgress` flag to pause `wire:poll` during Nostr login round-trip.
- 🔄 Removed redundant `Session::regenerate()` to avoid session ID conflicts.
- 🪲 Improved error handling for signature serialization and Nostr signer unavailability.
2026-05-04 00:36:00 +02:00
BT dc723855df **Nostr Login:** Improved CSRF token handling during login flow.
- 🛡️ Avoided redundant `Session::regenerate` call as `Auth::loginUsingId` already updates the session ID.
- 🚀 Replaced `wire:navigate` with a full-page redirect to ensure a fresh CSRF token for Livewire actions.
2026-05-04 00:15:37 +02:00
BT 2efc88a7f8 **Nostr Login:** Added server-side fallback for fresh challenges and improved client-side challenge resolution.
- 🔄 `requestNostrChallenge` now issues a new challenge when needed.
- 🛡️ Enhanced fallback logic in `nostrLogin.js` to ensure robust challenge retrieval.
-  Added test coverage for fresh challenge issuance.
2026-05-03 23:53:46 +02:00
BT bd7d39c1d7 **Nostr Login:** Enhanced error handling and removed unused auth-error event binding. 2026-05-03 23:41:49 +02:00
BT 0f26bae9a6 **Nostr Login:** Improved error handling and compatibility for Nostr login flow.
- 🛡️ Added validation for missing or invalid `challenge`.
- ⚠️ Added error handling for absent or non-functional Nostr signer.
- 🔄 Ensured plain serialization of signed events for Livewire compatibility.
- 🪲 Improved error messages for better user feedback.
2026-05-03 23:12:38 +02:00
The Ben 81d310257b Merge pull request #1 from HolgerHatGarKeineNode/claude/fix-security-flaws-vZgBB
Implement NIP-42 Nostr login and enhance security
2026-05-03 18:15:53 +00:00
BT a363c99453 🔥 **Cleanup & Tests:** Removed the obsolete auth.register component and its related route, feature tests, and browser tests. Disabled public registration and added tests to ensure /register returns a 404. Added new tests for service, lecturer, city, venue, and meetup CRUD flows. 2026-05-03 20:09:07 +02:00