Closed
Conversation
* Adding a playermanager and an extensions module for future extensions(other games and stuff) * Adding a playermanager and an extensions module for future extensions(other games and stuff) * fixed a minor issue from coupon db migrations * some more bug fixes * bug fixes * bug fixes * bug fixes * Final minecraft player manager update * MC player manager v1.0.1 yay * Items now properly render, enchants are listed properly, armor now shows up * mod support, and minor fixes * Better? * Minor player manager extension changes * some more fixes for the extensions/extension module permission changes * fix git typo * merge newer networking fixes * DiscordSrv helper extension, extension module improvements, server resource rendering bug fix * fixes * fork bugfix * DiscordSrv helper small ui change * floating windows: use theme colors for background and editor * Floating Windows yippe, extensions are bugged pls fix * idk * Custom domains yippe * Custom Domains support for Cname and srv records with multiple cf api keys, script that restarts services everytime you build the panel * Custom domain bug fixes * Small bug fix * Final custom domain fixes * Custom Domains now can be limited and show up in user billing * fixes * Unfinished wings-rs implementation,works overall only ssh activity logging is missing both in the panel and wings, minor bug found in custom domains not patched yet * Minor activity changes * Fixing stuff * Fixing stuff --------- Co-authored-by: macery12 <macen.elliott@gmail.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
Co-Authored-By: bimbab189 <79527589+bimbab189@users.noreply.github.com>
* feat: enforce default billing cycle and reseed on settings change - Fix BillingCycleService::validateBillingCycle() to reject billing days that do not match the global default when a product has no custom cycles, eliminating the 1-365 day open door for products without configured cycles - Add BillingCycleService::reseedDefaultBillingCycle() which, when the admin changes the default_billing_days setting, updates products that have exactly one billing cycle matching the old default to the new default, preserving all manually configured multi-cycle products unchanged - Inject BillingCycleService into BillingValidationService and call validateBillingCycle() inside calculatePriceWithCoupon() for new-order flows (orderType != 'ren'), covering Stripe, Mollie, PayPal, and free checkout - Hook reseedDefaultBillingCycle() into BillingController::settings() when the renewal:default_billing_days key is saved; the old value is captured before persisting so that the reseed knows which products to update - Update BillingValidationServiceTest to supply the new BillingCycleService mock - Add BillingCycleServiceTest with 7 unit tests covering both the validation enforcement and the no-op early-return of reseed Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/d38de8c9-1581-44bc-93ad-b2a5014fc57d Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * perf: use eager loading in reseedDefaultBillingCycle to avoid N+1 queries Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/d38de8c9-1581-44bc-93ad-b2a5014fc57d Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: return default billing cycle in getAllCycles when no custom cycles configured When a product has no billing cycles in the database, getAllCycles() was returning an empty array, causing the admin server billing UI to display "No billing cycles configured. Please configure billing cycles first." Apply the same fallback already present in getAvailableCycles(): return a synthetic entry for the global default_billing_days setting value so the endpoint always returns at least one selectable option. Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/ebd16b1b-88c8-4952-a986-cf91f5b1e94e Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: always sync billing cycles on update and filter synthetic defaults on load - Filter out synthetic default entries (no id) from getBillingCycles response so virtual fallbacks don't get saved as real DB rows when a product is saved - Always call syncBillingCycles on product update regardless of cycle count so deleting all cycles (empty array) properly removes them from the database Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/6db647a0-587c-4f5b-aa81-985a26d20466 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: allow empty cycles array in SyncBillingCyclesRequest Change 'required' to 'present' so saving a product with no billing cycles no longer fails validation. An empty array correctly clears all custom cycles and the service falls back to the global default billing days. Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/4e819767-6006-4c25-9068-dcfb503c4acc Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: NaN% for free products + remove debug logs from billing cycle code - Guard getDiscountPercent against division-by-zero when basePrice is 0 (free products displayed NaN% premium/discount label) - Remove console.log debug calls from billingCycles.ts API client - Remove \Log::info debug calls from BillingCycleController - Remove unused getMultiplierRanges export, MultiplierRanges interface, and the corresponding unused import in ProductForm.tsx Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/f88b8957-324a-4a89-a72a-f7041188dbea Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
* feat: implement jGuard admin-controlled registration service Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/1e58dd75-81ed-4f56-868c-3d72b5d37900 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * chore: improve pending table column header clarity Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/1e58dd75-81ed-4f56-868c-3d72b5d37900 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: jGuard settings use local state, add time remaining to pending table Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/ffb1e7d5-601b-41c2-a81e-1956e547aae1 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * feat: webhook on jGuard pending registration with approval mode/time info Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/4934a11e-557d-4027-9997-9a01c5ba544c Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * feat: webhook on jGuard pending registration with approval mode/time info Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/4934a11e-557d-4027-9997-9a01c5ba544c Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * style: simplify verbose comments across jGuard changes Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/0d1d9d07-144a-44dc-8198-d9f9ebf29c12 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: show pending approval screen immediately after jGuard registration/SSO Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/54c86c1e-18f6-42f4-8737-b96a02f3f200 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * Changes before error encountered Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/8d46cd6c-7fbc-4441-9102-f2b2f665437f Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * revert: go back to 2fe2a8d state + logout with alert on pending registration Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/b9be2897-7031-46ad-a8a7-8d083666fb17 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
* fix: use relative signed URL for email verification to prevent 403 on HTTPS Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/94bd0399-aa08-483d-a68a-4013e61a314e Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: robustly join app URL and signed path with single slash Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/94bd0399-aa08-483d-a68a-4013e61a314e Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * security: fix email verification and password reset abuse vectors - Fix #1 (critical): recovery-code verify used password_verify() on an encrypted (not hashed) value, making the flow always fail. Replace with Crypt::decryptString() + hash_equals() for a correct, timing-safe check. - Fix #2 (critical): UserUpdateService::handle() now nulls email_verified_at when the email address changes, preventing the verification bypass where a user could change to an unowned address and keep their verified status. - Fix #3 (medium): add throttle:6,1 to GET /email/verify/{id}/{hash} to prevent automated replay of captured verification links. - Fix #4 (medium): add throttle:password-reset-ip + throttle:password-reset-email to the legacy POST /password/reset (ResetPasswordController) route, which previously had no rate limiting. - Fix #5 (medium): add throttle:10,1 to GET /password-reset/method to prevent high-frequency probing of the system's reset configuration. - Fix #6 (medium): rotate the recovery code (generate + persist a fresh Crypt::encryptString value) immediately after a successful recovery-code reset so the code cannot be replayed. - Fix #8 (low): upgrade email hash in verification URL from SHA-1 to SHA-256 in both EmailVerificationService (link generation) and VerifyEmailController (link validation). - Fix #9 (low): replace url() helper in PasswordResetService::sendResetLink() with config('app.url') concatenation to produce correct HTTPS links when the panel is behind a TLS-terminating proxy. - Harden verify(): add full input validation (email, code, password/confirmed with Password::min rules) that was missing from the recovery-code path. Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/64163633-adf0-4f34-a66d-bdc6112d43f6 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
…ove OAuth warning (#221) Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/beb5b451-46cc-4b39-a989-e43a8785398f Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
* fix: read support email in footer from settings reply_to/from_email instead of hardcoded config Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/ba03eb79-8a68-4cec-94ec-9f907a5e089e Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: pass resolved replyTo into view data so footer reads correct support email Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/8338a677-9a07-4767-a8b1-4bba1f8f5894 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
#223) * feat: add email template viewer to admin email section Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/61c69990-a92b-4b6c-993b-3fefd8199443 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * chore: address code review comments - document iframe sandbox intent Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/61c69990-a92b-4b6c-993b-3fefd8199443 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: use srcdoc for iframe preview and add CSP header to backend Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/240bd7bb-d93d-4bd4-a2de-c1afde803db6 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix * Fix email footer support address to use settings-driven reply-to (#222) * fix: read support email in footer from settings reply_to/from_email instead of hardcoded config Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/ba03eb79-8a68-4cec-94ec-9f907a5e089e Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: pass resolved replyTo into view data so footer reads correct support email Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/8338a677-9a07-4767-a8b1-4bba1f8f5894 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> Co-authored-by: macery12 <macen.elliott@gmail.com>
* Add email template editor with source editing, variable docs, and preview Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/07c6b71a-5785-49b1-992c-90e832058168 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * Address review feedback: consolidate duplicate buttons, fix backup error handling Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/07c6b71a-5785-49b1-992c-90e832058168 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * Redesign template editor: 3-panel layout, view mode toggles, auto-load source Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/5c8c2870-d8d6-452a-9f35-e834bbb2e068 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * Fix split view: change editor/preview ratio to 50/50 Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/47325f56-343f-4e09-846d-ae22af70f3f1 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * test layout * Fix editor/preview layout: fixed height container so panes scroll independently Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/577aed83-640e-4a8e-adbc-a5ce878a28fe Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * Fix preview cutoff: use flex grow/shrink ratios instead of percentage basis Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/a4d33c57-3bc1-4547-9247-2865bbc7bab6 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * Remove Discard button; adjust editor/preview split to 30/70 Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/36f8ca18-9d66-4ca4-b3f2-dada38f36ed6 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> Co-authored-by: macery12 <macen.elliott@gmail.com>
* feat: add custom blade email override support to template editor Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/3f6c6ea6-b85e-492f-8c05-faf6578a6e0e Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: address code review feedback on custom template override Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/3f6c6ea6-b85e-492f-8c05-faf6578a6e0e Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: use dedicated request class for template revert to avoid 422 error Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/b27bf79d-78de-4782-9c38-e9fc314e5c5b Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
…ing accounts (#227) * Add Discord SSO password validation, link-choice page, and account linking Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/b14f53eb-e922-4893-a255-c31c068add42 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * Fix review issues: remove duplicate Values interface and console.error Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/b14f53eb-e922-4893-a255-c31c068add42 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * Fix handleReset crash on link-choice page and constrain Discord card width Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/3f9aa29c-5746-4ac7-a8a8-1049c0c9cb69 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * Fix Discord SSO registration password confirmation validation Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/5518a589-3682-477c-bddc-0c1ef6dbec9b Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
* perf: split vendor chunks, fix heroicons wildcard imports, lazy-load preset and auth sub-routes Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/31f1976a-c1a1-4dc3-9763-c7bcc19afe51 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * perf: split vendor-editor chunk from 1683kB into on-demand pieces; largest editor chunk is now 287kB Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/99d78601-a5d9-47e0-9ef7-d9647e71cadd Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * update pnpm lock * fix: merge @FortAwesome into vendor-react chunk to fix forwardRef crash at init time Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/c7b99343-16f9-40f4-b46a-a236b5068bb3 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: merge @codemirror/view into vendor-editor-core to fix TDZ crash at init time Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/3b9a04e8-ded8-4823-9d13-a51ed89a9837 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * docs: add VITE5_UPGRADE.md with phased migration guide Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/5341b90d-19da-49f4-be2e-1a7b9583d8c8 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> Co-authored-by: root <root@testpanel.macery12.xyz>
* chore: upgrade Vite 4 to Vite 5 with companion package upgrades Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/d6619c9e-371a-4bdf-a08e-2b059f9bf821 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: upgrade happy-dom to 20.8.9 to patch three security vulnerabilities Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/d6619c9e-371a-4bdf-a08e-2b059f9bf821 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * docs: add package audit and upgrade plan documents Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/88af3728-0f25-441d-9e17-c0d822ca50a7 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
* feat: add admin manual email verification in user settings Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/894429db-0234-4f1d-84cc-0ec1ef27341d Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: address code review feedback on email verification Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/894429db-0234-4f1d-84cc-0ec1ef27341d Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: use Button.Warn for unverify email to distinguish from verify Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/65c05364-3f84-4a11-b913-182d18eddf49 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/bb51bcc0-1f5f-4f41-8cae-ee2d38321c5e Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/25ee3d6d-6b8d-485e-8ae9-783c8595b093 Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/f4dc922b-7ea3-424c-b4e7-9962e4177bc1 Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
…ble button, Re-Add DKK currency (#233) * feat: Improve JGuard user-facing messaging and error presentation - Add configurable pending_message to JGuard settings (backend + frontend) - Replace browser alert popups with styled ScreenBlock error pages - Replace plain suspended div with branded ScreenBlock component - Remove window.alert from RegisterContainer and DiscordRegistrationContainer - Expose pending_message via EverestComposer and SettingsServiceProvider Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/46f18eeb-6737-4350-b428-01007c05461c Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: match textarea background to Input style, remove immediate approval mode - Replace raw <textarea> with Textarea styled component from @/elements/Input so the pending message field matches the Activation Delay input styling - Remove 'immediate' approval mode from Select, Alert block, type unions, backend validation, and config comment across all affected files Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/666e81b9-48dc-4044-85f0-ba72892807ac Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * style: give Disable jGuard module button a proper outlined red appearance Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/de2d7874-c770-4a71-9b93-9f704960eb51 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * merge: resolve conflicts with origin/main Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/121baaea-5439-48d4-82e9-617f2505b570 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: revert bad main merge, keep DKK, add logout button to suspended screen Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/fa82fb83-8f72-453c-abfe-33c4f3a69da0 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
…override lookup (#234) * fix: use custom email template overrides when sending emails Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/40c694b0-8651-474c-8fea-25f3f844f020 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: guard renderViewWithCustomOverride against path traversal Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/40c694b0-8651-474c-8fea-25f3f844f020 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: clear PHP stat cache in custom email template read/write paths Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/d2901688-17e3-442a-aa89-313d8a63b789 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: tighten regex to reject consecutive dots in view path guard Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/d2901688-17e3-442a-aa89-313d8a63b789 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * revert: remove clearstatcache additions from previous session Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/cded546c-c8e1-4d7d-b0f4-268988edae66 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/631dc42f-034f-4250-b38b-629392408275 Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
* security: harden Wings-RS endpoints — RBAC, upgrade, script.run, rate limits, TLS, opId validation Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * fix: update happy-dom 8.7.2 → ^20.8.9 and vitest 0.28.5 → ^1.6.0 to fix 3 CVEs Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/58d6dc65-a98e-49b6-8916-1b503714d55a Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> * revert: restore guzzle verify to environment('production') check, remove GUZZLE_VERIFY config key Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/cf876f9d-b3ed-4ed6-9865-30f7e2e1eeb9 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com> Co-authored-by: macery12 <macen.elliott@gmail.com>
- Add config/extensions.php with scanner configuration - Add ScanResult DTO (app/Services/Extensions/ScanResult.php) - Add ExtensionSecurityScanner service with phpcs/ESLint/Semgrep pipeline - Add extension:scan Artisan command (ScanExtensionCommand) - Integrate scan gate into existing p:extensions:install command - Add ExtensionScanController REST API (POST scan, GET scan-report) - Register extension scan routes in api-client.php - Add scanExtension.ts API client for the frontend - Add ExtensionScanStatus.tsx visual status component - Add ExtensionInstallModal.tsx upload/scan/install wizard modal Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/6582c23a-1d39-4506-97a6-cbdf8ccc47f4 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
- Respect extensions.scan.block_on_high config flag (high findings → WARNED when flag is false) - Use Symfony ExecutableFinder for cross-platform binary detection instead of Unix 'which' - Use File::put() for ESLint config file write to properly surface errors - Use configured temp_dir for upload storage path in ExtensionScanController Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/6582c23a-1d39-4506-97a6-cbdf8ccc47f4 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
Both ScanResult::toArray() and ExtensionSecurityScanner now explicitly check for 'WARNING' severity when counting Semgrep warnings, instead of using a negation pattern that would incorrectly include INFO findings. Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/6582c23a-1d39-4506-97a6-cbdf8ccc47f4 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Add extension security scanner pipeline for M12Labs
feat: extension security scanner pipeline
May 6, 2026
- Inject ExtensionSecurityScanner into ExtensionPackageInstallService and ExtensionPackageUpdateService; scan runs inside performInstallFileOps() and performUpdateFileOps() after download, before extraction — covering UI installs, repository-mode CLI installs, and all batch operations - Add `skipScan` param to installFromArchive()/updateFromArchive() so the CLI commands can skip the service-level scan after running their own interactive scan (avoids double-scanning file-mode archives) - UpdateExtensionCommand: add --skip-scan flag + interactive scan for file-mode updates (mirrors InstallExtensionCommand pattern) - InstallExtensionCommand: pass skipScan:true to service for file mode, inform user that repo-mode scan runs after download - ExtensionOperationProgress.tsx: add 'scanning'/'Security scan' step to INSTALL_STEPS and UPDATE_STEPS so it appears in the UI progress banner Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/991a8ac1-0d63-4d5a-a80d-e9849a2901f0 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
- ExtensionSecurityScanner: validate all zip entries against zip-slip attacks before extraction (paths must stay within target directory) - ExtensionSecurityScanner: check json_encode() return value and throw a RuntimeException instead of writing 'false' as the ESLint config - ExtensionInstallModal: update validation error message to mention both .M12LabsExtension and .zip accepted file types Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/991a8ac1-0d63-4d5a-a80d-e9849a2901f0 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
…ress service The previous session added progress reporting for the new 'scanning' stage but did not register it in the INSTALL_STAGES/UPDATE_STAGES allowlists. The report() method validates stages and throws InvalidArgumentException for unknown ones, which was caught by performInstallFileOps' generic catch and re-thrown as the "Failed to prepare the extension package for installation." 400 error seen when installing via the UI or CLI. Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/d5af09ed-822d-48b3-ad9b-afa731b0551a Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
…, phpcs files, semgrep rulesets, BLOCKED reports - Zip-slip: replace realpath()-based check (bypassed for non-existent paths) with string-normalization; throw early when '..' exhausts the stack - Zip-bomb: MAX_ZIP_ENTRIES=10_000 and MAX_EXTRACTED_BYTES=500MB guards checked before extraction in a single pre-scan loop - ESLint config: moved from the scanned directory to storage/app/tmp/<uuid>.json (application-controlled permissions), cleaned up in a finally block - phpcs: pass collected $phpFiles list instead of bare $dir so only PHP files are targeted (removes the redundant variable) - Semgrep rulesets: configurable via extensions.scan.semgrep_rulesets (env EXTENSIONS_SEMGREP_RULESETS), default p/php-security,p/javascript - BLOCKED scan reports: routed to extensions/blocked-scans/<slug>/ instead of extensions/installed/ to avoid orphaned files Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/f3bc0482-3f14-4d8e-8332-ab145a5ec7e0 Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
…e path fix; add test packages - runJsScan: detect ESLint major version; write flat .cjs config for v9+, legacy JSON for v8; set process CWD to scan dir so files are within ESLint's base path; resolve eslint-plugin-security path dynamically; set all security rules to 'error' so findings count as high-severity - binaryExists: handle absolute binary paths directly (is_file + is_executable) rather than relying on ExecutableFinder which only searches PATH - Add getEslintMajorVersion() and resolveNodeModule() helpers - Add jsString() helper for safe JS string literal generation - tools/test_packages/: add four test extension archives (BLOCKED, PASSED, INVALID_MANIFEST, NO_MANIFEST) for local and CI verification Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/962f6c3e-1344-4532-b7b7-dbd4b772419e Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
…binaryExists Agent-Logs-Url: https://github.com/macery12/M12Labs/sessions/962f6c3e-1344-4532-b7b7-dbd4b772419e Co-authored-by: macery12 <57544649+macery12@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
runJsScanfor ESLint v9/v10 flat config compatibilitybinaryExiststo correctly handle absolute binary paths (Unix + Windows drive letters)resolveNodeModulenull-safety: guard against ExecutableFinder returning null, support absolute eslint path, guard empty npm roottools/test_packages/with all four test extension archivessecurity_test_BLOCKED→ BLOCKED (2 high-severity: eval in PHP + JS) ✅security_test_PASSED→ PASSED (0 findings) ✅security_test_INVALID_MANIFEST→ ERROR (missing manifest fields) ✅security_test_NO_MANIFEST→ ERROR (missing m12labs-extension.json) ✅Original prompt
Overview
Implement a full extension security scanner pipeline for the M12Labs extension system. When a
.M12LabsExtensionfile (a renamed archive) is installed, the system must automatically scan all extracted PHP and TypeScript/JavaScript files for security vulnerabilities before allowing installation to proceed. The scan status must also be displayed in the frontend UI.Context
Everest\(maps toapp/)app/Extensions/(though the plugin/addon extension system is being built fresh)glob()inside aRoute::group— making pre-install scanning criticalapp/Console/Commands/and are auto-loaded byapp/Console/Kernel.phpvia$this->load(__DIR__ . '/Commands')app/Providers/resources/scripts/Backend Implementation
1.
app/Services/Extensions/ExtensionSecurityScanner.phpA service class with the following responsibilities:
Pipeline steps:
.M12LabsExtensionarchive (it's a renamed ZIP) to a unique temp directory understorage/app/extension-scans/{uuid}/extension.jsonexists inside with at minimumname,version,authorfields. Abort with aBLOCKEDresult if missing.phpcswith thephpcs-security-auditruleset on all.phpfiles found in the extracted dir:phpcsbinary is not available, log a warning and skip (do not block)ERRORseverity finding → add to high-severity listWARNING→ add to warnings listeslint-plugin-securityon all.ts,.tsx,.jsfiles:eslint-plugin-securityrules"severity": 2(error) → high-severity;"severity": 1→ warningssemgrepbinary is available on PATH:severity: ERROR→ high-severity; others → warningsScanResult::BLOCKEDScanResult::WARNEDScanResult::PASSEDstorage/app/extensions/installed/{extensionSlug}/scan-report.jsoncontaining:{ "scanned_at": "ISO8601", "outcome": "PASSED|WARNED|BLOCKED", "php_findings": [...], "js_findings": [...], "semgrep_findings": [...], "summary": { "high": 0, "warnings": 0 } }2.
app/Services/Extensions/ScanResult.phpA simple value object / DTO:
3.
app/Console/Commands/Extensions/ScanExtensionCommand.phpArtisan command:
php artisan extension:scan {path} {--report-only}{path}— path to the.M12LabsExtensionfile--report-only— run scan but don't block (useful for CI/auditing)1if BLOCKED (unless--report-only),0otherwise$this->table(),$this->error(),$this->warn(),$this->info()4.
app/Console/Commands/Extensions/InstallExtensionCommand.phpArtisan command:
php artisan extension:install {path}Full install pipeline:
ExtensionSecurityScanner::scan($path)$this->confirm('Proceed with warnings?'), abort if nostorage/app/extensions/installed/{slug}/, save manifest, save scan report5.
app/Http/Controllers/Api/Client/Extensions/ExtensionScanController.phpREST API controller:
POST /api/client/extensions/scan— acceptsmultipart/form-datawithextension_fileThis pull request was created from Copilot chat.