Skip to content

feat: add Custom Copyright Name and URL redirection#423

Closed
Xteri08 wants to merge 12 commits into
MineTrax:developfrom
Xteri08:main
Closed

feat: add Custom Copyright Name and URL redirection#423
Xteri08 wants to merge 12 commits into
MineTrax:developfrom
Xteri08:main

Conversation

@Xteri08

@Xteri08 Xteri08 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Added copyright name and optional copyright link fields to the General Settings page.
    • The site footer now uses the new copyright text and can link it when a URL is provided.
  • Bug Fixes

    • Improved validation for the new copyright link field to catch invalid URLs.
    • Existing footer display continues to fall back to the site name when no custom copyright name is set.

Xinecraft and others added 11 commits March 17, 2025 05:21
Add config to enable/disable username casting to lowercase.
in some vps input email is getting set as empty string.
New Theme Development & Upgrade Packages
Updated Russian lang/ru.json for MineTrax: full key parity with en.json, tightened terminology, and shorter UI-friendly copy where needed.
Copilot AI review requested due to automatic review settings July 3, 2026 16:22
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4650873a-e37b-4bd5-b241-6f95405324ce

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Adds copyright_name and copyright_url settings across backend validation, the GeneralSettings model, a new settings migration, the admin settings form, and footer rendering with an optional link. Includes feature tests and a full frontend asset rebuild reflecting new compiled bundle hashes.

Changes

Copyright Settings Feature

Layer / File(s) Summary
Backend validation, model, migration
app/Http/Controllers/Admin/Settings/GeneralSettingController.php, app/Settings/GeneralSettings.php, database/settings/2026_07_03_000000_add_copyright_fields_to_general_settings.php
Adds nullable copyright_name/copyright_url validation, model properties, and a migration registering/removing these settings keys.
Feature tests
tests/Feature/Admin/GeneralSettingTest.php
Tests viewing settings, updating/clearing copyright fields, and validating an invalid copyright_url.
Admin settings form UI
resources/default/js/Pages/Admin/Setting/GeneralSetting.vue
Adds form fields and inputs for copyright name and URL.
Footer rendering
resources/default/js/Shared/MainFooter.vue
Displays copyright name (falling back to site name) as a link when a URL is set.
Compiled asset rebuild
public/build/default/assets/AppLayout-*.js, GeneralSetting-*.js, DidYouKnowBox-*, many page bundles, manifest.json
Regenerates AppLayout and GeneralSetting bundles with new logic, updates DidYouKnowBox styles, and propagates new hashed import paths across dozens of page bundles and the manifest.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
    participant Admin
    participant GeneralSettingForm as GeneralSetting.vue
    participant Controller as GeneralSettingController
    participant Settings as GeneralSettings
    participant Footer as MainFooter.vue

    Admin->>GeneralSettingForm: Enter copyright_name / copyright_url
    GeneralSettingForm->>Controller: POST admin.setting.general.update
    Controller->>Controller: Validate copyright_name, copyright_url
    Controller->>Settings: Persist copyright_name, copyright_url
    Settings-->>Controller: Saved
    Controller-->>GeneralSettingForm: Redirect

    Footer->>Settings: Read copyright_name / copyright_url
    Settings-->>Footer: generalSettings values
    Footer->>Footer: Render name (link if copyright_url set)
Loading

Poem

A rabbit hops to the settings page,
Copyright fields, the newest stage 🐇
Name and URL, tucked in with care,
Footer now links with a hop and a flair.
Bundles rebuilt, hashes anew—
Carrots for tests that all came through! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly matches the main change: adding customizable copyright name and URL support in settings and footer display.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds configurable copyright text and optional link support to the default theme footer, with corresponding admin settings, persistence via Spatie Laravel Settings, and feature coverage via a new admin feature test.

Changes:

  • Added copyright_name and copyright_url fields to GeneralSettings (settings migration + model + controller validation/persistence).
  • Exposed the new fields in the Admin → General Settings UI and rendered them in the public footer (name falls back to site_name, optional link when URL is set).
  • Rebuilt the default theme’s Vite assets to reflect the UI/layout changes.

Reviewed changes

Copilot reviewed 51 out of 55 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/Feature/Admin/GeneralSettingTest.php Adds feature tests covering viewing settings, updating/clearing copyright fields, and URL validation.
resources/default/js/Shared/MainFooter.vue Renders footer copyright name with optional link based on new settings.
resources/default/js/Pages/Admin/Setting/GeneralSetting.vue Adds admin form inputs for copyright name and URL.
database/settings/2026_07_03_000000_add_copyright_fields_to_general_settings.php Adds new Spatie settings keys for copyright name/URL.
app/Settings/GeneralSettings.php Declares the new settings properties on GeneralSettings.
app/Http/Controllers/Admin/Settings/GeneralSettingController.php Validates and persists the new copyright fields on update.
public/build/default/assets/VerifyEmail-C1GmyK4v.js Rebuilt frontend bundle output.
public/build/default/assets/UserNotifications-DbaN5JQ3.js Rebuilt frontend bundle output.
public/build/default/assets/TwoFactorChallenge-CsYC4xI-.js Rebuilt frontend bundle output.
public/build/default/assets/ShowRecruitmentSubmission-4cDuWWaY.js Rebuilt frontend bundle output.
public/build/default/assets/ShowRecruitment-B_6TKadX.js Rebuilt frontend bundle output.
public/build/default/assets/ShowPost-DL4rAkJb.js Rebuilt frontend bundle output.
public/build/default/assets/ShowNews-BklNsAsV.js Rebuilt frontend bundle output.
public/build/default/assets/ShowDownload-B54z9tEn.js Rebuilt frontend bundle output.
public/build/default/assets/ShowCustomPage-BGBbka_s.js Rebuilt frontend bundle output.
public/build/default/assets/ShowCustomForm-ekog6_rV.js Rebuilt frontend bundle output.
public/build/default/assets/ShowBannedPage-z3IP0ckg.js Rebuilt frontend bundle output.
public/build/default/assets/Show-DfBy0FkQ.js Rebuilt frontend bundle output.
public/build/default/assets/ResetPassword-DR_OrH06.js Rebuilt frontend bundle output.
public/build/default/assets/ResetPassword-Bu2U0TJh2.js Rebuilt frontend bundle output.
public/build/default/assets/Register-BA7LIWVl.js Rebuilt frontend bundle output.
public/build/default/assets/PostRegistrationSetupUser-DgYGyXt2.js Rebuilt frontend bundle output.
public/build/default/assets/Login-CF66QZug.js Rebuilt frontend bundle output.
public/build/default/assets/IndexStaff-Btr1TPy-.js Rebuilt frontend bundle output.
public/build/default/assets/IndexSession-D6QGZcPE.js Rebuilt frontend bundle output.
public/build/default/assets/IndexRecruitmentSubmission-BTxiIw7O.js Rebuilt frontend bundle output.
public/build/default/assets/IndexRecruitment-wXp14ayp.js Rebuilt frontend bundle output.
public/build/default/assets/IndexPost-C-2jzH6F.js Rebuilt frontend bundle output.
public/build/default/assets/IndexPoll-Cgp0wFKZ.js Rebuilt frontend bundle output.
public/build/default/assets/IndexNews-uWEwoFtw.js Rebuilt frontend bundle output.
public/build/default/assets/IndexDownload-CKUXEhJE.js Rebuilt frontend bundle output.
public/build/default/assets/IndexCustomForm-BjczAtHQ.js Rebuilt frontend bundle output.
public/build/default/assets/Index-DPrLEHaJ.js Rebuilt frontend bundle output.
public/build/default/assets/GeneralSetting-APkzm_oO.js Removed old built asset after rebuild/renaming.
public/build/default/assets/ForgotPassword-GRtIbruC.js Rebuilt frontend bundle output.
public/build/default/assets/FeatureList-DeVJsV1P.js Rebuilt frontend bundle output.
public/build/default/assets/DidYouKnowBox-vj4xcv5k.css Rebuilt CSS asset output.
public/build/default/assets/DidYouKnowBox-B-54DjML.css Removed old built CSS asset after rebuild/renaming.
public/build/default/assets/ConfirmPassword-C4Imlc0M.js Rebuilt frontend bundle output.
public/build/default/assets/AppLayout-sUiMHh8S.js Added new built asset after rebuild/renaming.
public/build/default/assets/AppLayout-BohlXgWD.js Removed old built asset after rebuild/renaming.
Files not reviewed (3)
  • public/build/default/assets/AppLayout-sUiMHh8S.js: Generated file
  • public/build/default/assets/DidYouKnowBox-vj4xcv5k.css: Generated file
  • public/build/default/assets/GeneralSetting-Bj09Ll5Z.js: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 11 to +13
const generalSettings = usePage().props.generalSettings;
const displayCopyrightName = generalSettings.copyright_name || generalSettings.site_name;
const copyrightUrl = generalSettings.copyright_url;

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
app/Http/Controllers/Admin/Settings/GeneralSettingController.php (1)

27-67: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

New validation added inline; consider Form Request class.

The new copyright_name/copyright_url rules extend an already large inline validate() call. Per coding guidelines, controllers under app/Http/Controllers/** should use dedicated Form Request classes with rules and custom messages rather than inline validation. This is a pre-existing pattern throughout this method, so a full conversion is a larger effort than this PR's scope, but worth tracking for a future cleanup.

As per coding guidelines, "Always create Form Request classes for validation rather than inline validation in controllers; include both validation rules and custom error messages."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/Http/Controllers/Admin/Settings/GeneralSettingController.php` around
lines 27 - 67, The validation in GeneralSettingController should be moved out of
the inline $request->validate() call into a dedicated Form Request class. Create
a request for this settings update, move the existing rules from the controller
into its rules() method, and add the custom messages there as well so the
controller only handles the validated input and update flow.

Source: Coding guidelines

resources/default/js/Shared/MainFooter.vue (1)

502-511: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider target="_blank"/rel="noreferrer" for consistency with other external links.

Every other external link in this file (social icons) opens in a new tab with rel="noreferrer". The new copyright link navigates in the same tab, which is inconsistent and could unexpectedly take users away from the site.

♻️ Proposed fix
         <a
           v-if="copyrightUrl"
           :href="copyrightUrl"
+          target="_blank"
+          rel="noreferrer"
           class="hover:underline hover:text-primary"
         >
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@resources/default/js/Shared/MainFooter.vue` around lines 502 - 511, The
copyright link in MainFooter.vue is inconsistent with the other external links
in the footer, which use a new tab and noreferrer behavior. Update the anchor
rendered for the copyrightUrl branch in the MainFooter component to include
target="_blank" and rel="noreferrer", matching the existing social icon links
while keeping the v-if/v-else display logic unchanged.
resources/default/js/Pages/Admin/Setting/GeneralSetting.vue (1)

175-202: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Minor: missing autocomplete attribute for consistency.

Sibling URL fields in this form (discord_invite_url, youtube_url, etc.) set autocomplete="<field_name>", but the new copyright_name/copyright_url inputs omit it. Not functionally required, but inconsistent with the surrounding conventions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@resources/default/js/Pages/Admin/Setting/GeneralSetting.vue` around lines 175
- 202, The new XInput fields for copyright_name and copyright_url in
GeneralSetting.vue are missing the autocomplete attribute used by the other
URL/text inputs in this form. Add the matching autocomplete values to both
inputs, following the existing pattern in the same component (for example the
sibling discord_invite_url and youtube_url fields), so the new fields stay
consistent with the form conventions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@public/build/default/assets/AppLayout-sUiMHh8S.js`:
- Line 1: The copyright link validation currently allows non-web schemes, so
tighten the `copyright_url` rule in `GeneralSettingController` to accept only
`http` and `https` URLs before the value reaches `AppLayout`’s footer rendering.
Update the validation used for the general settings save flow so `copyright_url`
is restricted to web pages only, while keeping the existing `copyright_name`
behavior unchanged.

---

Nitpick comments:
In `@app/Http/Controllers/Admin/Settings/GeneralSettingController.php`:
- Around line 27-67: The validation in GeneralSettingController should be moved
out of the inline $request->validate() call into a dedicated Form Request class.
Create a request for this settings update, move the existing rules from the
controller into its rules() method, and add the custom messages there as well so
the controller only handles the validated input and update flow.

In `@resources/default/js/Pages/Admin/Setting/GeneralSetting.vue`:
- Around line 175-202: The new XInput fields for copyright_name and
copyright_url in GeneralSetting.vue are missing the autocomplete attribute used
by the other URL/text inputs in this form. Add the matching autocomplete values
to both inputs, following the existing pattern in the same component (for
example the sibling discord_invite_url and youtube_url fields), so the new
fields stay consistent with the form conventions.

In `@resources/default/js/Shared/MainFooter.vue`:
- Around line 502-511: The copyright link in MainFooter.vue is inconsistent with
the other external links in the footer, which use a new tab and noreferrer
behavior. Update the anchor rendered for the copyrightUrl branch in the
MainFooter component to include target="_blank" and rel="noreferrer", matching
the existing social icon links while keeping the v-if/v-else display logic
unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3d763207-4f25-430d-a575-15c800fdf370

📥 Commits

Reviewing files that changed from the base of the PR and between 341392b and 24bf36d.

📒 Files selected for processing (55)
  • app/Http/Controllers/Admin/Settings/GeneralSettingController.php
  • app/Settings/GeneralSettings.php
  • database/settings/2026_07_03_000000_add_copyright_fields_to_general_settings.php
  • public/build/default/assets/AppLayout-BohlXgWD.js
  • public/build/default/assets/AppLayout-sUiMHh8S.js
  • public/build/default/assets/ChangeSkin-BsoQt9Qb.js
  • public/build/default/assets/ConfirmPassword-C4Imlc0M.js
  • public/build/default/assets/Dashboard-C3DZBQRW.js
  • public/build/default/assets/Dev-CQf3DxpW.js
  • public/build/default/assets/DidYouKnowBox-4tcv07hI.js
  • public/build/default/assets/DidYouKnowBox-B-54DjML.css
  • public/build/default/assets/DidYouKnowBox-vj4xcv5k.css
  • public/build/default/assets/FeatureList-DeVJsV1P.js
  • public/build/default/assets/ForgotPassword-GRtIbruC.js
  • public/build/default/assets/GeneralSetting-APkzm_oO.js
  • public/build/default/assets/GeneralSetting-Bj09Ll5Z.js
  • public/build/default/assets/Index-DPrLEHaJ.js
  • public/build/default/assets/IndexCustomForm-BjczAtHQ.js
  • public/build/default/assets/IndexDownload-CKUXEhJE.js
  • public/build/default/assets/IndexNews-uWEwoFtw.js
  • public/build/default/assets/IndexPlayer-DVA9ZimN.js
  • public/build/default/assets/IndexPoll-Cgp0wFKZ.js
  • public/build/default/assets/IndexPost-C-2jzH6F.js
  • public/build/default/assets/IndexPunishment-C51aVZyf.js
  • public/build/default/assets/IndexRecruitment-wXp14ayp.js
  • public/build/default/assets/IndexRecruitmentSubmission-BTxiIw7O.js
  • public/build/default/assets/IndexSession-D6QGZcPE.js
  • public/build/default/assets/IndexStaff-Btr1TPy-.js
  • public/build/default/assets/ListLinkedPlayer-D38oU1v0.js
  • public/build/default/assets/Login-CF66QZug.js
  • public/build/default/assets/PostRegistrationSetupUser-DgYGyXt2.js
  • public/build/default/assets/Register-BA7LIWVl.js
  • public/build/default/assets/ResetPassword-Bu2U0TJh2.js
  • public/build/default/assets/ResetPassword-DR_OrH06.js
  • public/build/default/assets/Show-DfBy0FkQ.js
  • public/build/default/assets/ShowBannedPage-z3IP0ckg.js
  • public/build/default/assets/ShowCustomForm-ekog6_rV.js
  • public/build/default/assets/ShowCustomPage-BGBbka_s.js
  • public/build/default/assets/ShowDownload-B54z9tEn.js
  • public/build/default/assets/ShowNews-BklNsAsV.js
  • public/build/default/assets/ShowPlayer-DW9bY7WQ.js
  • public/build/default/assets/ShowPost-DL4rAkJb.js
  • public/build/default/assets/ShowPunishment-D9IuRtMU.js
  • public/build/default/assets/ShowRecruitment-B_6TKadX.js
  • public/build/default/assets/ShowRecruitmentSubmission-4cDuWWaY.js
  • public/build/default/assets/ShowSession-_wlWpsKz.js
  • public/build/default/assets/ShowUser-DaOKuWrp.js
  • public/build/default/assets/TwoFactorChallenge-CsYC4xI-.js
  • public/build/default/assets/UserNotifications-DbaN5JQ3.js
  • public/build/default/assets/VerifyEmail-C1GmyK4v.js
  • public/build/default/assets/app-kmrcdTlU.js
  • public/build/default/manifest.json
  • resources/default/js/Pages/Admin/Setting/GeneralSetting.vue
  • resources/default/js/Shared/MainFooter.vue
  • tests/Feature/Admin/GeneralSettingTest.php
💤 Files with no reviewable changes (3)
  • public/build/default/assets/AppLayout-BohlXgWD.js
  • public/build/default/assets/GeneralSetting-APkzm_oO.js
  • public/build/default/assets/DidYouKnowBox-B-54DjML.css

@@ -0,0 +1 @@
import{H as e,Q as t,S as n,T as r,U as i,V as a,Wt as o,b as s,h as c,v as l,vt as u,w as d,x as f,y as p,z as m,zt as h}from"./vue.runtime.esm-bundler-BdVAZHbZ.js";import{o as g}from"./dist-B6FUfOuV.js";import{n as _,nt as v,t as y}from"./BaseLayout-Cg9j9bFk.js";import{t as b}from"./Icon-CqJy4up6.js";var ee={key:0,id:`variant_1`,class:`container flex flex-col flex-wrap px-5 py-20 mx-auto md:items-center lg:items-start md:flex-row md:flex-no-wrap`},te={class:`shrink-0 w-64 mx-auto text-center md:mx-0 md:text-left`},ne={key:0,class:`my-4 text-sm text-foreground dark:text-foreground whitespace-pre-wrap`},re={class:`mt-4`},ie={class:`inline-flex justify-center mt-2 sm:ml-auto sm:mt-0 sm:justify-start`},ae=[`href`],oe=[`href`],se=[`href`],ce=[`href`],le=[`href`],ue=[`href`],de=[`href`],fe=[`href`],pe=[`href`],me=[`href`],he=[`href`],ge=[`href`],_e=[`href`],x={class:`flex flex-col flex-wrap grow mt-10 -mb-10 text-center md:flex-row md:pl-20 md:mt-0 md:text-left`},S={class:`mb-3 font-bold text-foreground dark:text-foreground`},C={class:`mb-10 list-none`},w=[`href`],T={key:1,id:`variant_2`,class:`bg-secondary`},E={class:`mx-auto max-w-5xl px-4 py-16 sm:px-6 lg:px-8`},D={class:`flex justify-center`},O={key:0,class:`mx-auto mt-6 max-w-md text-center whitespace-pre-wrap leading-relaxed text-foreground dark:text-foreground`},k={class:`mt-12 flex flex-wrap justify-center gap-6 md:gap-8 lg:gap-12`},A=[`href`],j={class:`mt-12 flex justify-center gap-6 md:gap-8`},M={key:0},N=[`href`],P={key:1},F=[`href`],I={key:2,class:`-mt-0.5`},ve=[`href`],ye={key:3,class:`-mt-0.5`},be=[`href`],xe={key:4},Se=[`href`],L={key:5},Ce=[`href`],we={key:6},Te=[`href`],Ee={key:7},De=[`href`],Oe={key:8},ke=[`href`],Ae={key:9},je=[`href`],Me={key:10},Ne=[`href`],Pe={key:11},Fe=[`href`],Ie={key:12},Le=[`href`],Re={class:`text-sm text-foreground dark:text-foreground`},ze=[`href`],Be={key:0,class:`text-xs text-foreground`},Ve={key:0},He=[`href`],R={__name:`MainFooter`,setup(e){let s=window._customfooter,l=!!s,_=!route().current(`admin.*`)&&l,y=g().props.generalSettings,R=y.copyright_name||y.site_name,z=y.copyright_url,B=y?.discord_invite_url,V=y?.youtube_url,H=y?.facebook_url,U=y?.twitter_url,W=y?.twitch_url,G=y?.tiktok_url,K=y?.linkedin_url,q=y.threads_url,J=y.instagram_url,Y=y.whatsapp_url,X=y.telegram_url,Z=y.reddit_url,Q=y.github_url,$=[];return s?.style==`variant_1`?$=s?.columns?.filter(e=>e.items.length>0)??[]:s?.style==`variant_2`&&($=s?.columns?.reduce((e,t)=>(e.push(...t.items),e),[])),(e,l)=>{let g=i(`InertiaLink`);return m(),n(`footer`,{class:h([`w-full text-foreground bg-sidebar body-font`,{"md:mt-28":u(_)}])},[u(_)&&u(s).style==`variant_1`?(m(),n(`div`,ee,[p(`div`,te,[r(g,{class:`flex md:justify-start justify-center`,href:e.route(`home`)},{default:t(()=>[r(v,{class:`block w-auto h-9`})]),_:1},8,[`href`]),u(s).site_moto?(m(),n(`p`,ne,o(u(s).site_moto),1)):f(``,!0),p(`div`,re,[p(`span`,ie,[u(H)?(m(),n(`a`,{key:0,target:`_blank`,href:u(H),class:`text-foreground cursor-pointer hover:text-foreground dark:hover:text-foreground`},[r(b,{name:`facebook`,class:`w-5 h-5 fill-current`})],8,ae)):f(``,!0),u(U)?(m(),n(`a`,{key:1,target:`_blank`,href:u(U),class:`ml-3 text-foreground cursor-pointer hover:text-foreground dark:hover:text-foreground`},[r(b,{name:`twitter`,class:`w-5 h-5 fill-current`})],8,oe)):f(``,!0),u(K)?(m(),n(`a`,{key:2,target:`_blank`,href:u(K),class:`ml-3 -mt-0.5 text-foreground cursor-pointer hover:text-foreground dark:hover:text-foreground`},[r(b,{name:`linkedin`,class:`h-5 fill-current`})],8,se)):f(``,!0),u(V)?(m(),n(`a`,{key:3,target:`_blank`,href:u(V),class:`ml-3 -mt-0.5 text-foreground cursor-pointer hover:text-foreground dark:hover:text-foreground`},[r(b,{name:`youtube`,class:`h-6 fill-current`})],8,ce)):f(``,!0),u(B)?(m(),n(`a`,{key:4,target:`_blank`,href:u(B),class:`ml-3 -mt-0.5 text-foreground cursor-pointer hover:text-foreground dark:hover:text-foreground`},[r(b,{name:`discord`,class:`h-6 fill-current`})],8,le)):f(``,!0),u(G)?(m(),n(`a`,{key:5,target:`_blank`,href:u(G),class:`ml-3 text-foreground cursor-pointer hover:text-foreground dark:hover:text-foreground`},[r(b,{name:`tiktok`,class:`w-5 h-5 fill-current`})],8,ue)):f(``,!0),u(W)?(m(),n(`a`,{key:6,target:`_blank`,href:u(W),class:`ml-3 text-foreground cursor-pointer hover:text-foreground dark:hover:text-foreground`},[r(b,{name:`twitch`,class:`w-5 h-5 fill-current`})],8,de)):f(``,!0),u(q)?(m(),n(`a`,{key:7,target:`_blank`,href:u(q),class:`ml-3 text-foreground cursor-pointer hover:text-foreground dark:hover:text-foreground`},[r(b,{name:`threads`,class:`w-5 h-5 fill-current`})],8,fe)):f(``,!0),u(J)?(m(),n(`a`,{key:8,target:`_blank`,href:u(J),class:`ml-3 text-foreground cursor-pointer hover:text-foreground dark:hover:text-foreground`},[r(b,{name:`instagram`,class:`w-5 h-5 fill-current`})],8,pe)):f(``,!0),u(Y)?(m(),n(`a`,{key:9,target:`_blank`,href:u(Y),class:`ml-3 text-foreground cursor-pointer hover:text-foreground dark:hover:text-foreground`},[r(b,{name:`whatsapp`,class:`w-5 h-5 fill-current`})],8,me)):f(``,!0),u(X)?(m(),n(`a`,{key:10,target:`_blank`,href:u(X),class:`ml-3 text-foreground cursor-pointer hover:text-foreground dark:hover:text-foreground`},[r(b,{name:`telegram`,class:`w-5 h-5 fill-current`})],8,he)):f(``,!0),u(Z)?(m(),n(`a`,{key:11,target:`_blank`,href:u(Z),class:`ml-3 text-foreground cursor-pointer hover:text-foreground dark:hover:text-foreground`},[r(b,{name:`reddit`,class:`w-5 h-5 fill-current`})],8,ge)):f(``,!0),u(Q)?(m(),n(`a`,{key:12,target:`_blank`,href:u(Q),class:`ml-3 text-foreground cursor-pointer hover:text-foreground dark:hover:text-foreground`},[r(b,{name:`github`,class:`w-5 h-5 fill-current`})],8,_e)):f(``,!0)])])]),p(`div`,x,[(m(!0),n(c,null,a(u($),(e,t)=>(m(),n(`div`,{key:t,class:`flex-1 px-4`},[p(`h3`,S,o(e.title),1),p(`nav`,C,[(m(!0),n(c,null,a(e.items,(e,r)=>(m(),n(`li`,{key:t+`-`+r,class:`mt-3`},[p(`a`,{href:e.url,class:`text-foreground dark:text-foreground dark:hover:text-foreground cursor-pointer hover:text-foreground`},o(e.title),9,w)]))),128))])]))),128))])])):f(``,!0),u(_)&&u(s).style==`variant_2`?(m(),n(`div`,T,[p(`div`,E,[p(`div`,D,[r(g,{class:`flex md:justify-start justify-center`,href:e.route(`home`)},{default:t(()=>[r(v,{class:`block w-auto h-9`})]),_:1},8,[`href`])]),u(s).site_moto?(m(),n(`p`,O,o(u(s).site_moto),1)):f(``,!0),p(`ul`,k,[(m(!0),n(c,null,a(u($),(e,t)=>(m(),n(`li`,{key:t},[p(`a`,{class:`text-foreground transition hover:text-foreground/75 dark:text-foreground dark:hover:text-foreground/75`,href:e.url},o(e.title),9,A)]))),128))]),p(`ul`,j,[u(H)?(m(),n(`li`,M,[p(`a`,{href:u(H),rel:`noreferrer`,target:`_blank`,class:`text-foreground transition hover:text-foreground/75 dark:text-foreground dark:hover:text-foreground`},[l[0]||=p(`span`,{class:`sr-only`},`Facebook`,-1),r(b,{name:`facebook`,class:`h-6 w-6 fill-current`})],8,N)])):f(``,!0),u(U)?(m(),n(`li`,P,[p(`a`,{href:u(U),rel:`noreferrer`,target:`_blank`,class:`text-foreground transition hover:text-foreground/75 dark:text-foreground dark:hover:text-foreground`},[l[1]||=p(`span`,{class:`sr-only`},`Twitter`,-1),r(b,{name:`twitter`,class:`h-6 w-6 fill-current`})],8,F)])):f(``,!0),u(K)?(m(),n(`li`,I,[p(`a`,{href:u(K),rel:`noreferrer`,target:`_blank`,class:`text-foreground transition hover:text-foreground/75 dark:text-foreground dark:hover:text-foreground`},[l[2]||=p(`span`,{class:`sr-only`},`LinkedIn`,-1),r(b,{name:`linkedin`,class:`h-6 w-6 fill-current`})],8,ve)])):f(``,!0),u(V)?(m(),n(`li`,ye,[p(`a`,{href:u(V),rel:`noreferrer`,target:`_blank`,class:`text-foreground transition hover:text-foreground/75 dark:text-foreground dark:hover:text-foreground`},[l[3]||=p(`span`,{class:`sr-only`},`YouTube`,-1),r(b,{name:`youtube`,class:`h-7 w-7 fill-current`})],8,be)])):f(``,!0),u(B)?(m(),n(`li`,xe,[p(`a`,{href:u(B),rel:`noreferrer`,target:`_blank`,class:`text-foreground transition hover:text-foreground/75 dark:text-foreground dark:hover:text-foreground`},[l[4]||=p(`span`,{class:`sr-only`},`Discord`,-1),r(b,{name:`discord`,class:`h-6 w-6 fill-current`})],8,Se)])):f(``,!0),u(G)?(m(),n(`li`,L,[p(`a`,{href:u(G),rel:`noreferrer`,target:`_blank`,class:`text-foreground transition hover:text-foreground/75 dark:text-foreground dark:hover:text-foreground`},[l[5]||=p(`span`,{class:`sr-only`},`TikTok`,-1),r(b,{name:`tiktok`,class:`h-6 w-6 fill-current`})],8,Ce)])):f(``,!0),u(W)?(m(),n(`li`,we,[p(`a`,{href:u(W),rel:`noreferrer`,target:`_blank`,class:`text-foreground transition hover:text-foreground/75 dark:text-foreground dark:hover:text-foreground`},[l[6]||=p(`span`,{class:`sr-only`},`Twitch`,-1),r(b,{name:`twitch`,class:`h-6 w-6 fill-current`})],8,Te)])):f(``,!0),u(q)?(m(),n(`li`,Ee,[p(`a`,{href:u(q),rel:`noreferrer`,target:`_blank`,class:`text-foreground transition hover:text-foreground/75 dark:text-foreground dark:hover:text-foreground`},[l[7]||=p(`span`,{class:`sr-only`},`Threads`,-1),r(b,{name:`threads`,class:`h-6 w-6 fill-current`})],8,De)])):f(``,!0),u(J)?(m(),n(`li`,Oe,[p(`a`,{href:u(J),rel:`noreferrer`,target:`_blank`,class:`text-foreground transition hover:text-foreground/75 dark:text-foreground dark:hover:text-foreground`},[l[8]||=p(`span`,{class:`sr-only`},`Instagram`,-1),r(b,{name:`instagram`,class:`h-6 w-6 fill-current`})],8,ke)])):f(``,!0),u(Y)?(m(),n(`li`,Ae,[p(`a`,{href:u(Y),rel:`noreferrer`,target:`_blank`,class:`text-foreground transition hover:text-foreground/75 dark:text-foreground dark:hover:text-foreground`},[l[9]||=p(`span`,{class:`sr-only`},`WhatsApp`,-1),r(b,{name:`whatsapp`,class:`h-6 w-6 fill-current`})],8,je)])):f(``,!0),u(X)?(m(),n(`li`,Me,[p(`a`,{href:u(X),rel:`noreferrer`,target:`_blank`,class:`text-foreground transition hover:text-foreground/75 dark:text-foreground dark:hover:text-foreground`},[l[10]||=p(`span`,{class:`sr-only`},`Telegram`,-1),r(b,{name:`telegram`,class:`h-6 w-6 fill-current`})],8,Ne)])):f(``,!0),u(Z)?(m(),n(`li`,Pe,[p(`a`,{href:u(Z),rel:`noreferrer`,target:`_blank`,class:`text-foreground transition hover:text-foreground/75 dark:text-foreground dark:hover:text-foreground`},[l[11]||=p(`span`,{class:`sr-only`},`Reddit`,-1),r(b,{name:`reddit`,class:`h-6 w-6 fill-current`})],8,Fe)])):f(``,!0),u(Q)?(m(),n(`li`,Ie,[p(`a`,{href:u(Q),rel:`noreferrer`,target:`_blank`,class:`text-foreground transition hover:text-foreground/75 dark:text-foreground dark:hover:text-foreground`},[l[12]||=p(`span`,{class:`sr-only`},`Github`,-1),r(b,{name:`github`,class:`h-6 w-6 fill-current`})],8,Le)])):f(``,!0)])])])):f(``,!0),p(`div`,{class:h([{"bg-sidebar border-t":u(_),"bg-background":!u(_)},`flex flex-col items-center justify-center p-5`])},[p(`div`,Re,[l[13]||=d(` © `,-1),u(z)?(m(),n(`a`,{key:0,href:u(z),class:`hover:underline hover:text-primary`},o(u(R)),9,ze)):(m(),n(c,{key:1},[d(o(u(R)),1)],64)),d(` `+o(new Date().getFullYear()),1)]),e.$page.props.showPoweredBy?(m(),n(`div`,Be,[d(o(e.__(`Powered with`))+` `,1),r(b,{class:`absolute inline-flex w-4 h-4 text-destructive opacity-75 animate-ping`,name:`heart-fill`}),r(b,{class:`relative inline-flex w-4 h-4 text-destructive`,name:`heart-fill`}),l[15]||=d(` by `,-1),l[16]||=p(`a`,{target:`_blank`,href:`https://minetrax.github.io`,class:`hover:underline hover:text-primary`},`MineTrax`,-1),e.$page.props.poweredByExtraName&&e.$page.props.poweredByExtraLink?(m(),n(`span`,Ve,[l[14]||=d(` & `,-1),p(`a`,{target:`_blank`,href:e.$page.props.poweredByExtraLink,class:`hover:underline hover:text-primary`},o(e.$page.props.poweredByExtraName),9,He)])):f(``,!0)])):f(``,!0)],2)],2)}}},z={key:0,class:`z-50 flex items-center h-12 font-semibold text-primary-foreground shadow-sm bg-primary`},B=[`href`],V={onmouseover:`this.stop();`,onmouseout:`this.start();`},H={__name:`HeaderBroadcastBar`,setup(e){let{generalSettings:t}=g().props,r=t?.header_broadcast_text,i=t?.header_broadcast_url,a=l(()=>!!t?.header_broadcast_text);return(e,t)=>a.value?(m(),n(`div`,z,[p(`a`,{class:`w-full mt-2 cursor-pointer`,target:`_blank`,href:u(i)},[p(`marquee`,V,o(u(r)),1)],8,B)])):f(``,!0)}},U={__name:`AppLayout`,setup(n){return(n,i)=>(m(),s(y,null,{default:t(()=>[r(_),r(H),e(n.$slots,`default`),r(R)]),_:3}))}};export{U as t}; No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find all references to copyright_url and related general settings validation.
rg -n --hidden --no-ignore-vcs "copyright_url|generalSettings|copyright_name|site_name" .

# Inspect likely backend validation files if found by name.
fd -a -t f -i "general|setting|settings|config|footer|copyright" .

Repository: MineTrax/minetrax

Length of output: 50374


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the Laravel URL validation rule implementation.
rg -n --hidden --no-ignore-vcs "function validateUrl|validateUrl\(" vendor/laravel framework app

# If present, inspect the validator source around the URL rule.
fd -a -t f "ValidatesAttributes.php" vendor | head -n 20

Repository: MineTrax/minetrax

Length of output: 364


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read the URL validation implementation and nearby helper methods.
sed -n '2725,2795p' vendor/laravel/framework/src/Illuminate/Validation/Concerns/ValidatesAttributes.php

# Also inspect any URL-related validator docs in the framework source if present.
rg -n "url validation|scheme|FILTER_VALIDATE_URL|http|https" vendor/laravel/framework/src/Illuminate/Validation -g '*.php'

Repository: MineTrax/minetrax

Length of output: 2383


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect Str::isUrl implementation and any allowed-scheme handling.
rg -n --hidden --no-ignore-vcs "function isUrl|isUrl\(" vendor/laravel/framework/src/Illuminate/Support/Str.php vendor/laravel/framework/src/Illuminate -g '*.php'

# Read the relevant section if found.
sed -n '1750,1835p' vendor/laravel/framework/src/Illuminate/Support/Str.php

Repository: MineTrax/minetrax

Length of output: 3009


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read the exact Str::isUrl implementation.
sed -n '593,660p' vendor/laravel/framework/src/Illuminate/Support/Str.php

Repository: MineTrax/minetrax

Length of output: 7207


Restrict copyright_url to http(s)
app/Http/Controllers/Admin/Settings/GeneralSettingController.php currently uses Laravel’s url rule, which accepts non-http(s) schemes. If this footer link should only point to web pages, constrain it to http/https before saving.

🧰 Tools
🪛 ESLint

[error] 1-1: 'e' is defined but never used.

(no-unused-vars)


[error] 1-1: Missing semicolon.

(semi)


[error] 1-1: Missing semicolon.

(semi)


[error] 1-1: 'e' is defined but never used.

(no-unused-vars)


[error] 1-1: 'e' is defined but never used.

(no-unused-vars)


[error] 1-1: 't' is defined but never used.

(no-unused-vars)


[error] 1-1: Missing semicolon.

(semi)


[error] 1-1: 'n' is defined but never used.

(no-unused-vars)


[error] 1-1: 'i' is defined but never used.

(no-unused-vars)


[error] 1-1: Missing semicolon.

(semi)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@public/build/default/assets/AppLayout-sUiMHh8S.js` at line 1, The copyright
link validation currently allows non-web schemes, so tighten the `copyright_url`
rule in `GeneralSettingController` to accept only `http` and `https` URLs before
the value reaches `AppLayout`’s footer rendering. Update the validation used for
the general settings save flow so `copyright_url` is restricted to web pages
only, while keeping the existing `copyright_name` behavior unchanged.

@Xteri08 Xteri08 changed the base branch from main to develop July 3, 2026 17:53
@Xteri08

Xteri08 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

too much conflict, switching to develop branch directly.

@Xteri08 Xteri08 closed this Jul 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants