Hacks & Customizations
These hacks are unsupported customizations meant as unofficial workarounds.
They can cause instability, introduce issues and may conflict with future updates. Apply at your own risk!

Username-based Login

  • Author: @ssddanbrown
  • Created: 25th Nov 2022
  • Updated: 8th Oct 2024
  • Last Tested On: v24.05.4

This is a hack to BookStack, using the theme system, so that login presents itself as a username. Upon login attempt, this will match to a user of <username>@<configured-domain> within the database.

Considerations

  • This assumes all users in your BookStack instance shares the same email domain.
  • This overrides a large part of the login form so be extra aware this will be overriding any default changes to BookStack upon updates.
  • Login page errors may still reference email address, and username will not be auto prefilled after failed login submission.
  • Other functionality within BookStack can still require or use email, so it’s generally a good idea to ensure the resulting email addresses would be valid, or email is disabled at a system level in some manner.

Options

  • Change the $emailDomain variable on line 8 of functions.php to be the common email domain used in your BookStack instance (This will be auto-appended to usernames on login).

Code

functions.php
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

use BookStack\Facades\Theme;
use BookStack\Theming\ThemeEvents;
use Illuminate\Http\Request;

// The email domain to auto-append to usernames
$emailDomain = 'example.com';

// Listen for login requests in passing requests
Theme::listen(ThemeEvents::WEB_MIDDLEWARE_BEFORE, function (Request $request) use ($emailDomain) {
    if ($request->path() === 'login' && $request->method() === 'POST') {
        // If there's a username in a login request, convert that
        // to an 'email' input using our email domain.
        $username = $request->input('username', '');
        if ($username) {
            $request->request->remove('username');
            $request->request->add(['email' => $username . '@' . $emailDomain]);
        }
    }
});
auth/parts/login-form-standard.blade.php
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<form action="{{ url('/login') }}" method="POST" id="login-form" class="mt-l">
    {!! csrf_field() !!}

    <div class="stretch-inputs">
        <div class="form-group">
            <label for="username">{{ trans('auth.username') }}</label>
            @include('form.text', ['name' => 'username', 'autofocus' => true])
            @if($errors->has('email'))
                <div class="text-neg text-small">{{ $errors->first('email') }}</div>
            @endif
        </div>

        <div class="form-group">
            <label for="password">{{ trans('auth.password') }}</label>
            @include('form.password', ['name' => 'password'])
            <div class="small mt-s">
                <a href="{{ url('/password/email') }}">{{ trans('auth.forgot_password') }}</a>
            </div>
        </div>
    </div>

    <div class="grid half collapse-xs gap-xl v-center">
        <div class="text-left ml-xxs">
            @include('form.custom-checkbox', [
                'name' => 'remember',
                'checked' => false,
                'value' => 'on',
                'label' => trans('auth.remember_me'),
            ])
        </div>

        <div class="text-right">
            <button class="button">{{ Str::title(trans('auth.log_in')) }}</button>
        </div>
    </div>

</form>

Request an Update

Hack not working on the latest version of BookStack?
You can request this hack to be updated & tested for a small one-time fee.
This helps keeps these hacks updated & maintained in a sustainable manner.


Latest Hacks