Sessions · Reference
Laravel SDK
mybeast/sessions-laravel signs the token each page carries, keeps the journey of your signed-in people, pushes your key flows and erases a person's data when you ask. For Laravel 12 and 13 on PHP 8.2 or later.
Install
composer require mybeast/sessions-laravelThe service provider registers itself. To change the config, publish it to config/mybeast-sessions.php:
php artisan vendor:publish --tag=mybeast-sessions-configThe recorder itself is the browser SDK's: Browser SDK.
The .env lines
MYBEAST_SESSIONS_URL=https://services.my-beast.com/sessions
MYBEAST_SESSIONS_PUBLIC_KEY=pk_…
MYBEAST_SESSIONS_SIGNING_KEY=sig_…
MYBEAST_SESSIONS_SECRET=sk_…
MYBEAST_SESSIONS_ENVIRONMENT=production
# Optional: the journey
MYBEAST_SESSIONS_JOURNEY=trueA missing or malformed line switches that part off, and the SDK never throws at boot: without the keys, clientConfig() returns null and nothing is recorded; without the server secret, no journey is kept and Sessions is never asked. In tests, and in a checkout without the service, set MYBEAST_SESSIONS_ENABLED=false.
While the keys are in place, clientConfig() throws an InvalidArgumentException for a subject or account that isn't an id of 1 to 64 letters, digits and . _ : -, or an environment name that isn't up to 32 letters, digits, _ and -.
Configuration
| Key | Default | What it does |
|---|---|---|
enabledMYBEAST_SESSIONS_ENABLED | true | false switches everything off: tests, a checkout without the service. |
urlMYBEAST_SESSIONS_URL | none | The service: https://services.my-beast.com/sessions. |
public_keyMYBEAST_SESSIONS_PUBLIC_KEY | none | pk_…: names the project in the browser. Not a secret. |
signing_keyMYBEAST_SESSIONS_SIGNING_KEY | none | sig_…: signs the token each page carries. Keep it on the server. |
secretMYBEAST_SESSIONS_SECRET | none | sk_…: the server secret for the journey, key flows, objections, erasure and the test read-back. Recordings alone don't need it. |
environmentMYBEAST_SESSIONS_ENVIRONMENT | APP_ENV, else production | Sent with everything: one of the project's environments. Lowercase letters, digits, _ and -. |
token_ttlMYBEAST_SESSIONS_TOKEN_TTL | 1800 | How long a page's token lives, in seconds: 60 to 3600. Each response brings a fresh one. |
The journey's keys, under journey:
| Key | Default | What it does |
|---|---|---|
journey.enabledMYBEAST_SESSIONS_JOURNEY | false | Keeps the journey. Needs the URL and the server secret too. |
journey.middleware | true | The SDK adds its middleware to the end of the web group. false: add RecordJourneyStep where you want it, once. |
journey.skip_routes | [] | Route names (* wildcards) that are no one's step: autosaves, polling, pages never to be followed. |
journey.data_reads | [] | JSON reads that are steps (route names, * wildcards): a list's data a key flow counts. Kept as visits. |
journey.error_toast | 'error' | The flash key of the toast a refused write shows. A write that flashes it is a refused step. |
journey.server_error_toasts | [] | How the toasts that stand for a server error begin. Those make the step an error. |
journey.request_id_header | 'X-Request-Id' | The header with the request's id, so a step opens exactly its lines in Logs. null: none. |
journey.flows | null | Your key flows: a class implementing KeyFlows. |
journey.spool_pathMYBEAST_SESSIONS_SPOOL_PATH | storage/app/private/mybeast-sessions-spool | Where steps wait to be sent: files, never the database. Each server keeps its own. |
journey.flush_afterMYBEAST_SESSIONS_FLUSH_AFTER | 10 | Seconds the oldest step waits before a response sends the spool. 0: after every response that kept a step. |
Artisan commands
| Command | What it does |
|---|---|
mybeast:sessions-flush | Sends the journey steps waiting in the spool. The SDK schedules it every minute while the journey is on, so the scheduler must run. While the SDK is off it says so and succeeds. |
mybeast:sessions-flows | Checks your key flows and pushes them, replacing the ones Sessions has: a deploy step. Fails with every problem named when a definition doesn't fit, also while the SDK is off. |
mybeast:sessions-flows --check | Only checks the definitions and sends nothing: for CI. |
The Sessions facade
MyBeast\Sessions\Laravel\Facades\Sessions. The methods that ask Sessions need the server secret, and return null (or do nothing) without it. For an id that no token could carry, other than 1 to 64 of letters, digits and . _ : -, they answer 0 (or nothing) without asking: nothing is kept under it.
| Method | Returns | What it does |
|---|---|---|
clientConfig(subject, account, consentAt, mask, internal, test) | array or null | A page's config: {url, key, env, token, expires_at}. Records only with consentAt. null while the SDK is off. |
enabled() | bool | Whether pages can be given a config: the URL, the public key and the signing key are in place. |
environment() | string | The environment sent with everything. |
journeyEnabled() | bool | Whether the journey is kept: switched on, with the URL and the server secret. |
journeyUsing(subject, account, subjectSince, allows, serverError, page) | void | How the journey knows your people. Each hook optional; call it from a service provider's boot(). See Who the person is. |
pageShown(route, page) | bool | One visit step for a page the browser showed from its cache. Never throws. |
routeForAddress(address) | string or null | The name of your GET route for an address's path. |
flush() | int | Sends the steps waiting in the spool now; returns how many left it, taken or refused for good. |
keyFlows() | KeyFlows or null | Your key flows, from journey.flows. |
syncFlows(flows) | int or null | Pushes the key flows; returns how many Sessions has. What mybeast:sessions-flows runs. |
objected(subject) | int or null | The person objects to the journey: theirs is erased. Returns how many steps went. |
objectionLifted(subject) | void | Their journey is kept again from now on. |
eraseSubject(subject) | int or null | Erases every recording of the person. Returns how many went. |
eraseAccount(account) | int or null | Erases every recording made in the account, whoever it was of. |
eraseJourney(subject) | int or null | Erases the person's journey: steps, key flow runs, stuck point occurrences. |
eraseAccountJourney(account) | int or null | Erases the journey kept in the account, whoever it was about. |
testRecordings(subject) | array or null | A test person's recordings, read back: see Check your masking before you ship. |
fake() | JourneyFake | For tests: the journey on, its steps kept in memory. |
Exceptions
The calls that change something at Sessions throw when Sessions doesn't confirm them. Call them from a queued job with retries, so an erasure is never lost to a network blip. Asking again is safe: an erasure answers 0 the second time.
| Exception | Thrown by |
|---|---|
MyBeast\Sessions\Laravel\ErasureFailed | eraseSubject, eraseAccount, objected, eraseJourney, eraseAccountJourney |
MyBeast\Sessions\Laravel\ObjectionNotLifted | objectionLifted |
MyBeast\Sessions\Laravel\ExportFailed | testRecordings |
MyBeast\Sessions\Laravel\Flows\InvalidFlows | keyFlows, syncFlows: a definition doesn't fit, and nothing was sent |
MyBeast\Sessions\Laravel\Flows\FlowSyncFailed | syncFlows: Sessions didn't take the flows |
Testing
Sessions::fake() switches the journey on and keeps its steps in memory: nothing is written to the spool, nothing is sent.
use MyBeast\Sessions\Laravel\Facades\Sessions;
public function test_saving_a_project_is_a_step(): void
{
$journey = Sessions::fake(); // the journey on, steps in memory: nothing written, nothing sent
$this->actingAs(User::factory()->create())->post('/projects', ['name' => 'Shop']);
$journey->assertRecordedRoute('projects.store', 'save');
$journey->assertNotRecorded(fn (array $step) => $step['kind'] === 'refused');
}The fake also has assertRecorded(fn), assertRecordedCount(n), assertNothingRecorded(), recorded(fn), last() and its steps. Each step is the array Sessions would get. For the calls that ask Sessions, such as objected() or syncFlows(), use Laravel's Http::fake().
No recordings in tests