Skip to content

refactor: check auth after event#7

Merged
dipesh79 merged 1 commit into
masterfrom
log
Sep 21, 2025
Merged

refactor: check auth after event#7
dipesh79 merged 1 commit into
masterfrom
log

Conversation

@dipesh79
Copy link
Copy Markdown
Owner

@dipesh79 dipesh79 commented Sep 21, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Ensures activity logs are created only when a user is authenticated, improving accuracy and preventing logs with missing user context.
    • Increases reliability of create/update/delete logging across different execution contexts.
  • Refactor

    • Moved authentication checks inside event handlers to make logging behavior more consistent without changing existing log contents or structure.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Sep 21, 2025

Walkthrough

Moved authentication checks from around event listener registrations into the closures for created, updated, and deleted events in HasLog.php. Listeners are always registered; log creation executes only when auth()->check() is true. Log payload structure remains the same.

Changes

Cohort / File(s) Summary
Model logging trait
src/Traits/HasLog.php
Shifted auth guard inside created/updated/deleted event closures; maintained payload fields (action, ip_address, device, user_id; plus old_data and changed_values for updates). Restructured braces accordingly; public method signatures unchanged.

Sequence Diagram(s)

sequenceDiagram
  participant Model as Eloquent Model (uses HasLog)
  participant Listener as Event Listener (closure)
  participant Auth as Auth
  participant Log as Log Creator

  Model->>Listener: created/updated/deleted
  Listener->>Auth: check()
  alt Authenticated
    Listener->>Log: create(action, ip, device, user_id[, old_data, changed_values])
    Log-->>Listener: saved
  else Not authenticated
    Listener-->>Model: no-op
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

I hop through hooks where events reside,
Moved guards inside where checks now guide.
If user’s known, the logs will bloom,
If not, I pause—no need to boom.
Soft paws on code, a tidy glide. 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "ref: check auth after event" is concise and directly describes the primary change—moving the auth check into/after the event listener closures—so it accurately reflects the main intent and is clear enough for teammates scanning history.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch log

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 and usage tips.

@dipesh79 dipesh79 changed the title ref: check auth after event refactor: check auth after event Sep 21, 2025
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/Traits/HasLog.php (3)

19-25: Don't define boot() in a trait; use bootHasLog() to avoid collisions and guarantee execution.

A trait-level boot() can be overridden by the model’s own boot(), silently disabling your listeners. Prefer Eloquent’s trait boot hook.

-    public static function boot()
+    protected static function bootHasLog(): void
     {
-        /**
-         * The parent boot method is called to ensure that the parent boot method is not overridden.
-         */
-        parent::boot();
+        // Booted via Eloquent's bootTraits; don't override the model's boot().

10-12: Remove $listeners; it’s not an Eloquent construct and is unused here.

This property is for Livewire/components, not models; keeping it can confuse readers.

-    protected $listeners = [
-        'log' => 'log',
-    ];

43-54: Capture pre-update snapshot and stop logging full originals (PII risk)

src/Traits/HasLog.php — the updated handler currently calls json_encode($model->getRawOriginal()) inside static::updated; that both risks leaking sensitive attributes and may not capture the true "before" state because originals are synced during save.

  • Capture a sanitized pre-save snapshot in static::updating (use getOriginal() and getDirty(), then Arr::except to remove sensitive keys) and persist that sanitized snapshot in static::updated()->afterCommit() when creating the Log.
  • Use optional(request())->ip(), optional(request())->userAgent(), and auth()->id() instead of request()/auth()->user()->id to avoid null errors.
  • Prefer a whitelist ($logOnly) or blacklist ($logExcept) on models and a central masker for secrets (password, remember_token, api_token, access_token, etc.) — do not log full originals.

Example pattern:

static::updating(function($m){
  if (! auth()->check()) return;
  $sensitive = ['password','remember_token','api_token','access_token'];
  $m->__log_original = Arr::except($m->getOriginal(), $sensitive);
  $m->__log_dirty    = Arr::except($m->getDirty(), $sensitive);
});

static::updated(function($m){
  if (! auth()->check()) return;
  $m->logs()->create([
    'action'=>'Update',
    'ip_address'=>optional(request())->ip(),
    'device'=>optional(request())->userAgent(),
    'user_id'=>auth()->id(),
    'old_data'=>json_encode($m->__log_original ?? []),
    'changed_values'=>json_encode($m->__log_dirty ?? $m->getChanges()),
  ]);
})->afterCommit();
🧹 Nitpick comments (3)
src/Traits/HasLog.php (3)

29-38: Auth check move is good; tighten helpers and write after commit.

Use auth()->id(), early return, null-safe request(), and run after DB commit to avoid logging rolled-back ops.

-        static::created(function ($model) {
-            if (auth()->check()) {
-                $model->logs()->create([
-                    'action' => 'Create',
-                    'ip_address' => request()->ip(),
-                    'device' => request()->userAgent(),
-                    'user_id' => auth()->user()->id
-                ]);
-            }
-        });
+        static::created(function ($model) {
+            if (! auth()->check()) return;
+            $model->logs()->create([
+                'action' => 'Create',
+                'ip_address' => optional(request())->ip(),
+                'device' => optional(request())->userAgent(),
+                'user_id' => auth()->id(),
+            ]);
+        })->afterCommit();

59-68: Apply the same helper/after-commit improvements here; consider forceDeleted as well.

Use auth()->id(), optional(request()), early return, and ->afterCommit(). If you use soft deletes, also log forceDeleted.

-        static::deleted(function ($model) {
-            if (auth()->check()) {
-                $model->logs()->create([
-                    'action' => 'Delete',
-                    'ip_address' => request()->ip(),
-                    'device' => request()->userAgent(),
-                    'user_id' => auth()->user()->id
-                ]);
-            }
-        });
+        static::deleted(function ($model) {
+            if (! auth()->check()) return;
+            $model->logs()->create([
+                'action' => 'Delete',
+                'ip_address' => optional(request())->ip(),
+                'device' => optional(request())->userAgent(),
+                'user_id' => auth()->id(),
+            ]);
+        })->afterCommit();

29-68: DRY up repeated payload construction.

Extract a small helper to build and persist the log entry; closures call it with just the action.

Example (outside the shown ranges):

protected function writeUserLog(string $action, array $extra = []): void
{
    if (! auth()->check()) return;

    $base = [
        'action' => $action,
        'ip_address' => optional(request())->ip(),
        'device' => optional(request())->userAgent(),
        'user_id' => auth()->id(),
    ];

    $this->logs()->create($base + $extra);
}

Then:

  • created: $model->writeUserLog('Create');
  • updated: $model->writeUserLog('Update', ['old_data' => json_encode(...), 'changed_values' => json_encode(...)]); etc.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bf3d228 and 6c198f2.

📒 Files selected for processing (1)
  • src/Traits/HasLog.php (2 hunks)
🔇 Additional comments (1)
src/Traits/HasLog.php (1)

43-54: Gate ->afterCommit usage — verify framework support

composer.json has no laravel/illuminate requirement and there's no composer.lock, so the repo's Laravel version is unknown. Do not add ->afterCommit unconditionally in src/Traits/HasLog.php (the updated listener). Either require & document a minimum Laravel version that supports ->afterCommit, or add a runtime guard/fallback (detect support or use DB::afterCommit/polyfill) before using ->afterCommit.

@dipesh79 dipesh79 merged commit 8f94ffc into master Sep 21, 2025
3 of 4 checks passed
@dipesh79 dipesh79 deleted the log branch September 21, 2025 05:17
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.

1 participant