Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Ecommerce Laravel Laravel Package

liberusoftware/ecommerce-laravel

Liberu eCommerce for Laravel is a modular package for building online stores with product catalogs, shopping carts, checkout, order management, and payment workflows. Configurable, extensible, and Laravel-native, it gives developers a practical foundation for custom storefronts and ecommerce applica...

View on GitHub
Deep Wiki
Context7

Getting Started

Pin the version first. Packagist still resolves v13.0.0 as highest for composer create-project — that's the old Laravel-major-tagged line. v1.0.3 is the current one, so:

composer create-project liberu-ecommerce/ecommerce-laravel:1.0.3 my-store
# or in an existing app
composer require liberu-ecommerce/ecommerce-laravel:^1.0.3

If you're upgrading from v1.0.2, the fix is a straight composer update; there are no API removals, no config renames, no migrations in this release. But read the behaviour change below before deploying — registration no longer hands out access.

Where to look first:

  1. app/Actions/Fortify/CreateNewUser.php — the registration contract. A registrant now becomes a shopper: user, no team, no role, nothing else.
  2. app/Providers/Filament/*PanelProvider.php / the User::canAccessPanel() method — panel gating.
  3. app/Policies/TeamPolicy.php — create is the gate for team creation and requires the create_store permission.
  4. database/seeders/ — RolesSeeder no longer creates staff; DefaultTeamSeeder creates the merchant's own team owned by the admin.

First use case: seed the database, register a user through /register, and confirm the result is a shopper who lands on the storefront and can reach /orders, /wishlist, /invoices, /payment_methods but not /app. Then log in as the admin from DefaultTeamSeeder and grant that user a team via the panel. That single loop exercises everything this release changed.

The key mental model to adopt on day one: team membership is the permission. A user with no team is a customer. A user with a team is staff. Admin is a separate gate (super_admin role). Nothing else grants /app.

Implementation Patterns

Shopper-first registration. Don't reintroduce team assignment into CreateNewUser. If you need a merchant to auto-provision a team, do it explicitly after registration using the same path the UI uses — TeamPolicy::create behind the create_store permission — so you can't accidentally bypass the gate you'd otherwise be enforcing:

$user = User::create([...]);
// do NOT: $user->teams()->attach(Team::first());
$user->assignRole('staff'); // also do NOT — staff isn't seeded any more

If your fork genuinely needs provisioning at signup, write a dedicated action that checks $user->can('create', Team::class) and is covered by a test that registers through the real route.

Panel access is per-panel, resolve from $this. canAccessPanel now inspects the panel ID and reads $this rather than auth()->user() — that second detail matters anytime you check access for a user who isn't the session user (impersonation, admin "view as", queued provisioning). Follow the same pattern for any panel you add:

public function canAccessPanel(Panel $panel): bool
{
    return match ($panel->getId()) {
        'admin' => $this->hasRole('super_admin'),
        'app'   => $this->teams()->exists(),
        default => false,
    };
}

Treat default => false as non-negotiable. The bug this release fixed was literally return true; // TODO.

Rely on intended() for the storefront. Login and register both redirect to the storefront, but interrupted flows (checkout, add-to-cart, wishlist) resume correctly because the redirect honours the intended URL. Keep that: don't hardcode redirect()->route('shop') in your own auth controllers or Fortify response classes, or you'll drop shoppers mid-checkout.

Grant teams explicitly, test the denial. Anything that hands out a team should be behind a policy check, and every such feature deserves a negative test — a user without create_store attempting it must fail. The reason CI was green through this bug was a test helper (FortifyActionsTest::makeTeam()) that created both the team and the staff role, so the real path was never exercised. Write helpers that mirror production exactly: a registrant helper should produce a user with zero teams and zero roles.

Close the policy gap before you expose anything. ArticleResource and CollectionResource have no policy, and strictAuthorization is off, so Filament lets any team member CRUD their tenant's articles and collections — price included — with no permission check. A stranger can't reach it (that takes a team), but any newly invited staff member can. Doing it properly needs two things together: policies and seeded permissions, because the Shield permission set contains no article_* / collection_* entries at all. If you only add policies, everyone gets a 403; if you only seed permissions, nothing enforces them. Add both in one PR and turn strictAuthorization on for those resources.

Gotchas and Tips

The version number is a trap and will bite again. v13.0.0 (old Laravel-major scheme) still outranks 1.0.3 on Packagist. Pin 1.0.3 / ^1.0.3 in composer.json and in any create-project scaffolding, README snippets, or Dockerfiles. The v1 tag now points at this line, but tags don't change resolution order — constraints do.

Registration and panel access are one bug, not two. If you merge a hotfix that restores team assignment at signup without also fixing canAccessPanel, you've opened /app to every registrant with a role the seeder no longer creates. Change them together or not at all. Concretely: Team::first() returned the merchant's own team (or null and fataled), and RolesSeeder had stopped making staff back in cf711cb — either half alone fails closed, but a partial fix fails open.

permission.teams is false, so roles are global even though plenty of code reads as team-scoped. Don't assume role checks are isolated per tenant. If you need tenant-scoped roles, that's a config flip plus a permissions-table migration plus an audit of every hasRole/can call — treat it as a project, not a setting.

SVG stored XSS is latent and arms itself. Product upload accepts image/svg+xml onto a public disk. It's unreachable only because public/storage isn't linked yet. The moment anyone runs php artisan storage:link during deploy, it goes live. Either strip image/svg+xml from the accepted MIME list or run uploads through a sanitizer/image validation rule before you link storage in a real environment.

/user/profile 500s if you enable social login. // use HasConnectedAccounts; is commented out on User, so connectedAccounts is null and Socialstream calls ->map() on it. If you're turning on Socialstream, uncomment the trait in the same commit — don't debug the profile controller first, the stack trace points at the wrong place.

Password rules are weak by default. Password::default() is min 8 with no complexity and no breach check. In production, add ->mixedCase()->numbers()->symbols() and uncompromised() in your FortifyServiceProvider — this is a one-liner you'll otherwise forget.

The demo storefront ships sold out. DefaultTeamSeeder (or the product seeder) sets inventory_count = 0 on every product. If a fresh install looks broken — add-to-cart disabled, "sold out" badges everywhere — that's the seeder, not the install.

RoleBasedRedirect is dead code inherited from a property-management app; all six of its redirect targets 404. Don't follow it as an example of how the app handles post-login routing, and delete it if you're forking.

Debugging access failures: log $user->teams()->count(), $user->getRoleNames(), and $user->can('create', Team::class) before touching Filament. With team membership as the single gate for /app and super_admin for /admin, almost every "I can't get in" report resolves to one of those three values — and a user who can't get in but should is usually a missing create_store permission, not a missing role.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator