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

Nova Profile Tool Laravel Package

runlinenl/nova-profile-tool

Nova Profile Tool adds a dedicated profile page to Laravel Nova, letting authenticated users update their name, email, password, and avatar without leaving the admin panel. Simple to install and easy to customize.

View on GitHub
Deep Wiki
Context7

Getting Started

Check the Nova constraint before you type composer require. The last release (1.1.2, Dec 2018) only made field labels translatable; the stack is still Nova 2.x / Vue 2. Read the package's composer.json for its laravel/nova constraint and compare with composer show laravel/nova. On Nova 3+ you are forking, loosening the constraint, and rebuilding the compiled assets — budget for that up front.

Minimal install on a compatible Nova 2 app:

composer require runlinenl/nova-profile-tool
php artisan vendor:publish --provider="Runline\ProfileTool\ToolServiceProvider"

Register the tool in app/Providers/NovaServiceProvider.php:

use Runline\ProfileTool\ProfileTool;

public function tools()
{
    return [
        new ProfileTool(),
    ];
}

Then open the published config before writing a line of code. config/nova-profile-tool.php holds the field definitions and is the package's real API surface — it is where you will spend most of your time. Read it end to end: which fields ship by default (name, email, password), how the avatar field is configured (disk, storage path), and what shape a custom field entry takes. That file tells you more about day-to-day usage than the README does.

Confirm the route, don't assume it. Check the tool's route registration (php artisan route:list | grep -i profile) and hit the page as a seeded Nova user on a non-production environment. The first use case is the full round trip: change your name, change your email, change your password, and then verify in the database — email updated on your user row, password now a $2y$... hash that Hash::check() accepts. If both hold, the package behaves and you can start extending the config. If either fails, you found a fork-worthy bug on day one, before you built anything on top of it.

Implementation Patterns

Do all field customization in the published config. Adding a job_title or phone field means adding an entry to config/nova-profile-tool.php, not editing vendor views. Keeping the diff in config keeps your fork mergeable when you eventually patch the package, and it keeps the "what fields does a user edit?" question answerable from one file during review.

Own the authorization boundary yourself. The package ships no notion of "users edit only themselves." Add a tool-level gate:

return [
    (new ProfileTool())->canSee(fn ($request) => $request->user() !== null),
];

And in anything you write around the package, resolve the target user from auth()->user() — never from a route parameter or request payload. If you ever find an ID being accepted, that's a security bug, not a feature.

Route writes through an observer rather than patching the package. Email and password changes are the two places where the package's 2018 scope shows. Attach a UserObserver and handle the consequences outside the tool:

class UserObserver
{
    public function updated(User $user): void
    {
        if ($user->wasChanged('email')) {
            // clear email_verified_at / dispatch re-verification, notify old + new address, log
        }

        if ($user->wasChanged('password')) {
            // audit log; if using AuthenticateSession, invalidate other sessions
        }
    }
}

This keeps the package as a pure form while your app retains its verification, notification and audit guarantees. It also means the same rules apply when a password is changed from anywhere else.

Add "current password required" in the fork, not the config. It's not in the package. Add a current_password field plus Laravel's current_password validation rule to the tool's update handler. This is the single most valuable hardening change for an admin panel where sessions can be left open on a shared machine.

Handle the avatar deliberately. The package supports an optional avatar upload with configurable disk and path. Decide where it lives (usually the public disk), run php artisan storage:link if it's a new disk, and check the config's storage path matches your backup/retention expectations. If you only support initials-based avatars, drop the field from config rather than leaving a broken uploader.

Use 1.1.2's translatable labels properly. Publish the lang files, confirm keys are namespaced (profile-tool::fields.name), and override via resources/lang/{locale}/vendor/profile-tool/fields.php. Never edit vendor lang files. Every field you add in config needs a matching key in every locale you ship — otherwise a raw profile-tool::fields.job_title string appears in the UI, which is exactly the kind of thing that ships to production unnoticed.

For example, a custom field in config plus matching lang entries:

// config/nova-profile-tool.php
'fields' => [
    // ...
    'job_title' => [
        'label' => 'profile-tool::fields.job_title',
        'type'  => 'text',
        'rules' => ['nullable', 'string', 'max:120'],
    ],
],
// resources/lang/nl/vendor/profile-tool/fields.php
return ['job_title' => 'Functietitel'];

Isolate the tool behind a thin adapter. Even when the package works today, wrap registration and any custom field logic behind one class of your own. When Nova upgrades or the package is abandoned, you replace one file rather than hunting call sites. Pin the exact version ("runlinenl/nova-profile-tool": "1.1.2") and put the fork/upgrade task in the backlog with a named owner — otherwise it becomes an invisible dependency.

Write the tests the package doesn't ship. Four tests cover the meaningful regression surface: password is stored hashed and Hash::check() passes; a user cannot reach another user's data via URL manipulation; changing email resets verification; validation messages render under each supported locale. These are small test files and they're the cheapest insurance you'll get on an auth-adjacent tool.

Gotchas and Tips

  • Stale compiled frontend assets are the classic "nothing happened" bug. The shipped JS targets Nova 2's webpack toolchain. On a newer Nova the Vue app may silently fail to mount and the page just looks inert. Check the browser console before you debug PHP — a no-op page with no network activity is a bundle problem, not a backend problem. Fix requires npm install && npm run prod in a fork.

  • Never force the install with --ignore-platform-reqs. If composer require fails on the Nova constraint, that's the package telling you the truth. Forcing it converts a clean install failure into a confusing runtime failure days later.

  • The published config wins and isn't refreshed by composer update. If a field is missing or behaving oddly, check config/nova-profile-tool.php first — the package default may have changed upstream while your published copy stayed put.

  • Verify hashing against the database, not the toast. It is possible to see a "profile updated" success message while the stored value isn't a valid hash (a misconfigured hashed cast on your User model will do it). Run Hash::check('new-password', $user->password) against a freshly fetched row after your first change. Passwords are the one field where a silent failure locks people out.

  • Test the authorization boundary explicitly. Log in as user A and try to reach user B's profile by mutating any ID in the URL or payload. The package has no test suite to catch this for you; it is the highest-risk thing in the codebase.

  • Locale switching changes messages, not rules. Submit a bad email under each supported locale and confirm the displayed message and the validation both behave. Also sanity-check your email column collation and uniqueness with non-Latin input before rolling out to a multilingual team.

  • Watch for translation key collisions. If your host app already defines fields.name in an unnamespaced lang file, the package's labels can silently shadow (or be shadowed by) yours. Grep your lang folder before publishing; if there's overlap, switch to namespaced keys in your fork.

  • Have a rollback plan before pilots with real users. This touches authentication. Snapshot the users table and prepare a manual reset path (a tinker snippet with Hash::make, or a one-off artisan command) so a botched change doesn't lock the whole team out of Nova.

  • Read the package source once, fully. It is small. An hour spent reading the service provider, the tool class and the update handler will tell you exactly where it resolves the user, how it persists, and which Nova 2 field types it can render — which is faster than discovering the limits field by field during a sprint.

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.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package