Also fixed audit log to work for non-entity items.
use BookStack\Entities\Entity;
use BookStack\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
+use Illuminate\Support\Str;
/**
* @property string $type
return trans('activities.' . $this->type);
}
+ /**
+ * Check if this activity is intended to be for an entity.
+ */
+ public function isForEntity(): bool
+ {
+ return Str::startsWith($this->type, [
+ 'page_', 'chapter_', 'book_', 'bookshelf_'
+ ]);
+ }
+
/**
* Checks if another Activity matches the general information of another.
*/
const ROLE_UPDATE = 'role_update';
const ROLE_DELETE = 'role_delete';
- // TODO - Implement all below
- const ACCESS_PASSWORD_RESET = 'access_password_reset_request';
- const ACCESS_PASSWORD_RESET_UPDATE = 'access_password_reset_update';
- const ACCESS_LOGIN = 'access_login';
- const ACCESS_FAILED_LOGIN = 'access_failed_login';
+ const AUTH_PASSWORD_RESET = 'auth_password_reset_request';
+ const AUTH_PASSWORD_RESET_UPDATE = 'auth_password_reset_update';
+ const AUTH_LOGIN = 'auth_login';
+ const AUTH_REGISTER = 'auth_register';
}
\ No newline at end of file
<?php namespace BookStack\Auth\Access;
+use BookStack\Actions\ActivityType;
use BookStack\Auth\SocialAccount;
use BookStack\Auth\User;
use BookStack\Auth\UserRepo;
use BookStack\Exceptions\UserRegistrationException;
+use BookStack\Facades\Activity;
use Exception;
class RegistrationService
$newUser->socialAccounts()->save($socialAccount);
}
+ Activity::add(ActivityType::AUTH_REGISTER, $socialAccount ?? $newUser);
+
// Start email confirmation flow if required
if ($this->emailConfirmationService->confirmationRequired() && !$emailConfirmed) {
$newUser->save();
<?php namespace BookStack\Auth\Access;
+use BookStack\Actions\ActivityType;
use BookStack\Auth\User;
use BookStack\Exceptions\JsonDebugException;
use BookStack\Exceptions\SamlException;
use BookStack\Exceptions\UserRegistrationException;
+use BookStack\Facades\Activity;
use Exception;
use Illuminate\Support\Str;
use OneLogin\Saml2\Auth;
}
auth()->login($user);
+ Activity::add(ActivityType::AUTH_LOGIN, "saml2; {$user->logDescriptor()}");
return $user;
}
}
<?php namespace BookStack\Auth\Access;
+use BookStack\Actions\ActivityType;
use BookStack\Auth\SocialAccount;
use BookStack\Auth\UserRepo;
use BookStack\Exceptions\SocialDriverNotConfigured;
use BookStack\Exceptions\SocialSignInAccountNotUsed;
use BookStack\Exceptions\UserRegistrationException;
+use BookStack\Facades\Activity;
use Illuminate\Support\Str;
use Laravel\Socialite\Contracts\Factory as Socialite;
use Laravel\Socialite\Contracts\Provider;
// Simply log the user into the application.
if (!$isLoggedIn && $socialAccount !== null) {
auth()->login($socialAccount->user);
+ Activity::add(ActivityType::AUTH_LOGIN, $socialAccount);
return redirect()->intended('/');
}
<?php namespace BookStack\Auth;
+use BookStack\Interfaces\Loggable;
use BookStack\Model;
-class SocialAccount extends Model
+/**
+ * Class SocialAccount
+ * @property string $driver
+ * @property User $user
+ * @package BookStack\Auth
+ */
+class SocialAccount extends Model implements Loggable
{
protected $fillable = ['user_id', 'driver', 'driver_id', 'timestamps'];
{
return $this->belongsTo(User::class);
}
+
+ /**
+ * @inheritDoc
+ */
+ public function logDescriptor(): string
+ {
+ return "{$this->driver}; {$this->user->logDescriptor()}";
+ }
}
namespace BookStack\Http\Controllers\Auth;
+use BookStack\Actions\ActivityType;
use BookStack\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
use Illuminate\Http\Request;
$request->only('email')
);
+ if ($response === Password::RESET_LINK_SENT) {
+ $this->logActivity(ActivityType::AUTH_PASSWORD_RESET, $request->get('email'));
+ }
+
if ($response === Password::RESET_LINK_SENT || $response === Password::INVALID_USER) {
$message = trans('auth.reset_password_sent', ['email' => $request->get('email')]);
$this->showSuccessNotification($message);
namespace BookStack\Http\Controllers\Auth;
use Activity;
+use BookStack\Actions\ActivityType;
use BookStack\Auth\Access\SocialAuthService;
use BookStack\Exceptions\LoginAttemptEmailNeededException;
use BookStack\Exceptions\LoginAttemptException;
-use BookStack\Exceptions\UserRegistrationException;
use BookStack\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
}
}
+ $this->logActivity(ActivityType::AUTH_LOGIN, $user);
return redirect()->intended($this->redirectPath());
}
namespace BookStack\Http\Controllers\Auth;
+use BookStack\Actions\ActivityType;
use BookStack\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
use Illuminate\Http\Request;
{
$message = trans('auth.reset_password_success');
$this->showSuccessNotification($message);
+ $this->logActivity(ActivityType::AUTH_PASSWORD_RESET_UPDATE, user());
return redirect($this->redirectPath())
->with('status', trans($response));
}
'audit_deleted_item_name' => 'Name: :name',
'audit_table_user' => 'User',
'audit_table_event' => 'Event',
- 'audit_table_item' => 'Related Item',
+ 'audit_table_related' => 'Related Item or Detail',
'audit_table_date' => 'Activity Date',
'audit_date_from' => 'Date Range From',
'audit_date_to' => 'Date Range To',
<th>
<a href="{{ sortUrl('/settings/audit', $listDetails, ['sort' => 'key']) }}">{{ trans('settings.audit_table_event') }}</a>
</th>
- <th>{{ trans('settings.audit_table_item') }}</th>
+ <th>{{ trans('settings.audit_table_related') }}</th>
<th>
<a href="{{ sortUrl('/settings/audit', $listDetails, ['sort' => 'created_at']) }}">{{ trans('settings.audit_table_date') }}</a></th>
</tr>
{{ $activity->entity->name }}
</div>
</a>
- @elseif($activity->detail)
+ @elseif($activity->detail && $activity->isForEntity())
<div class="px-m">
{{ trans('settings.audit_deleted_item') }} <br>
{{ trans('settings.audit_deleted_item_name', ['name' => $activity->detail]) }}
</div>
+ @elseif($activity->detail)
+ <div class="px-m">{{ $activity->detail }}</div>
@endif
</td>
<td>{{ $activity->created_at }}</td>