Logical theme system example: IP based access permissions #2819

Closed
opened 2026-02-05 05:18:42 +03:00 by OVERLORD · 29 comments
Owner

Originally created by @AuthorShin on GitHub (May 29, 2022).

As per https://github.com/BookStackApp/BookStack/issues/3374#issuecomment-1140344900, re-purposing this to provide a logical theme system example.


Describe the feature you'd like

Hello
Thanks for building BookStack

I would like to see an option to limit the access for some /pages/books/shelves based on (public) viewer public IP address so it will check with a list of IPs in the settings that you already provided the works as whitelist.

Describe the benefits this would bring to existing BookStack users

For instance you have a public BookStack on your server and it's publicly available to everyone but there are pages and books and you don't want people to see/access so you set custom permissions for it but each time for accessing it you have to login, which is no problem for one or two device but for like 10 or more in the office it's nightmarish and imagine you have multi-factor authentication enabled as well.
So, how it will help? well in those cases all those devices are on the same network so will have the same public IP address and BookStack will override the custom permissions and let them access/see the pages/books/shelves that are not publicly available for the IP addresses that are not in the whitelist even though the user did not logged in.

Can the goal of this request already be achieved via other means?

Not sure.

Have you searched for an existing open/closed issue?

  • I have searched for existing issues and none cover my fundemental request

How long have you been using BookStack?

0 to 6 months

Additional context

No response

Originally created by @AuthorShin on GitHub (May 29, 2022). As per https://github.com/BookStackApp/BookStack/issues/3374#issuecomment-1140344900, re-purposing this to provide a logical theme system example. --- ### Describe the feature you'd like Hello Thanks for building BookStack I would like to see an option to limit the access for some /pages/books/shelves based on (public) viewer public IP address so it will check with a list of IPs in the settings that you already provided the works as whitelist. ### Describe the benefits this would bring to existing BookStack users For instance you have a public BookStack on your server and it's publicly available to everyone but there are pages and books and you don't want people to see/access so you set custom permissions for it but each time for accessing it you have to login, which is no problem for one or two device but for like 10 or more in the office it's nightmarish and imagine you have multi-factor authentication enabled as well. So, how it will help? well in those cases all those devices are on the same network so will have the same public IP address and BookStack will override the custom permissions and let them access/see the pages/books/shelves that are not publicly available for the IP addresses that are not in the whitelist even though the user did not logged in. ### Can the goal of this request already be achieved via other means? Not sure. ### Have you searched for an existing open/closed issue? - [ ] I have searched for existing issues and none cover my fundemental request ### How long have you been using BookStack? 0 to 6 months ### Additional context _No response_
OVERLORD added the 🔨 Feature Request label 2026-02-05 05:18:42 +03:00
Author
Owner

@AuthorShin commented on GitHub (May 29, 2022):

Duplicate :/

@AuthorShin commented on GitHub (May 29, 2022): Duplicate :/
Author
Owner

@ssddanbrown commented on GitHub (May 29, 2022):

Updated the issue details and re-opening as a task for myself to provide an example.

@ssddanbrown commented on GitHub (May 29, 2022): Updated the issue details and re-opening as a task for myself to provide an example.
Author
Owner

@ssddanbrown commented on GitHub (Jun 8, 2022):

Hi @AuthorShin,
As promised, here's an example of using the Logical theme system to enable this functionality in some form.

The below enables auto-login to specific user accounts based upon certain IP addresses.

Setup

You should already have a themes/ folder within your BookStack directory.
Within this create a custom directory, then within that create a functions.php file with the code from the below themes/custom/functions.php section.

Within your BookStack .env file, add the below line to set your theme folder:

APP_THEME=custom

Within your themes/custom/functions.php file, You can edit the IP-address mapping on around lines 17-19 (Within the $userIdsByIp array). This functions.php file is fully commented to describe what each section does.
The way this is done means that you can still login via another user by going directly to the /login path on your instance if required.

Note: This is essentially an unsupported functionality addition. There may be logical holes in usage and this could break upon future updates.

themes/custom/functions.php file

<?php

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

// Register a new web-middleware-before hook to authenticate as a specific user depending
// on IP address. Takes a request and always returns null to indicate we don't want to
// change the response provided back to the user.
Theme::listen(ThemeEvents::WEB_MIDDLEWARE_BEFORE, function (Request $request) {

    // A mapping of IP addresses to system user IDs.
    // You can add multiple entries here to map many IPs to user accounts.
    // In this example, requests coming from the IP '127.0.0.1' will be logged
    // in as the user with an ID of '3' in the database.
    $userIdsByIp = [
        '127.0.0.1' => 3,
    ];

    // A list of path prefixes we want to ignore to allow some normal auth activities (e.g. Login)
    $ignorePathsPrefixes = ['login', 'register', 'password'];

    // Gather the path and IP of the current request
    $path = $request->path();
    $ip = $request->ip();

    // Track whether the request is allowed for our auto-ip-login logic based upon checking
    // the request path against the above $ignorePathsPrefixes
    $autoLoginPath = true;
    foreach ($ignorePathsPrefixes as $pathPrefix) {
        if (strpos($path, $pathPrefix) === 0) {
            $autoLoginPath = false;
        }
    }

    // If we're already logged-in, don't attempt any login logic and quit out early.
    // If the path is not an auto-login path, and they're using an auto-login IP,
    // log the user out to allow access to normal login functions if desired.
    if (auth()->check()) {
        if (isset($userIdsByIp[$ip]) && !$autoLoginPath) {
            auth()->logout();
        }
        return null;
    }

    // If the current IP address is in our '$userIdsByIp' mapping, and if the path is
    // an auto-login path, look-up the user and log them in. This will force a
    // failure if the user ID is not found in the system.
    if (isset($userIdsByIp[$ip]) && $autoLoginPath) {
        $userId = $userIdsByIp[$ip];
        $user = User::query()->findOrFail($userId);
        auth()->login($user);
    }

    return null;
});
@ssddanbrown commented on GitHub (Jun 8, 2022): Hi @AuthorShin, As promised, here's an example of using the [Logical theme system](https://github.com/BookStackApp/BookStack/blob/development/dev/docs/logical-theme-system.md) to enable this functionality in some form. The below enables auto-login to specific user accounts based upon certain IP addresses. ### Setup You should already have a `themes/` folder within your BookStack directory. Within this create a `custom` directory, then within that create a `functions.php` file with the code from the below `themes/custom/functions.php` section. Within your BookStack `.env` file, add the below line to set your theme folder: ```bash APP_THEME=custom ``` Within your `themes/custom/functions.php` file, You can edit the IP-address mapping on around lines 17-19 (Within the `$userIdsByIp` array). This functions.php file is fully commented to describe what each section does. The way this is done means that you can still login via another user by going directly to the `/login` path on your instance if required. Note: This is essentially an unsupported functionality addition. There may be logical holes in usage and this could break upon future updates. ### `themes/custom/functions.php` file ```php <?php use BookStack\Auth\User; use BookStack\Facades\Theme; use BookStack\Theming\ThemeEvents; use Illuminate\Http\Request; // Register a new web-middleware-before hook to authenticate as a specific user depending // on IP address. Takes a request and always returns null to indicate we don't want to // change the response provided back to the user. Theme::listen(ThemeEvents::WEB_MIDDLEWARE_BEFORE, function (Request $request) { // A mapping of IP addresses to system user IDs. // You can add multiple entries here to map many IPs to user accounts. // In this example, requests coming from the IP '127.0.0.1' will be logged // in as the user with an ID of '3' in the database. $userIdsByIp = [ '127.0.0.1' => 3, ]; // A list of path prefixes we want to ignore to allow some normal auth activities (e.g. Login) $ignorePathsPrefixes = ['login', 'register', 'password']; // Gather the path and IP of the current request $path = $request->path(); $ip = $request->ip(); // Track whether the request is allowed for our auto-ip-login logic based upon checking // the request path against the above $ignorePathsPrefixes $autoLoginPath = true; foreach ($ignorePathsPrefixes as $pathPrefix) { if (strpos($path, $pathPrefix) === 0) { $autoLoginPath = false; } } // If we're already logged-in, don't attempt any login logic and quit out early. // If the path is not an auto-login path, and they're using an auto-login IP, // log the user out to allow access to normal login functions if desired. if (auth()->check()) { if (isset($userIdsByIp[$ip]) && !$autoLoginPath) { auth()->logout(); } return null; } // If the current IP address is in our '$userIdsByIp' mapping, and if the path is // an auto-login path, look-up the user and log them in. This will force a // failure if the user ID is not found in the system. if (isset($userIdsByIp[$ip]) && $autoLoginPath) { $userId = $userIdsByIp[$ip]; $user = User::query()->findOrFail($userId); auth()->login($user); } return null; }); ```
Author
Owner

@ssddanbrown commented on GitHub (Jun 8, 2022):

Since the above has been provided I'll therefore close this off but feel free to still comment here if you have questions or need additional guidance.

@ssddanbrown commented on GitHub (Jun 8, 2022): Since the above has been provided I'll therefore close this off but feel free to still comment here if you have questions or need additional guidance.
Author
Owner

@AuthorShin commented on GitHub (Jun 24, 2022):

@ssddanbrown
Thanks a lot man for the time and effort.
Is this supposed to work if the BookStack is installed as a Docker container?

@AuthorShin commented on GitHub (Jun 24, 2022): @ssddanbrown Thanks a lot man for the time and effort. Is this supposed to work if the BookStack is installed as a Docker container?
Author
Owner

@ssddanbrown commented on GitHub (Jun 24, 2022):

@AuthorShin Being a docker container should not make too much of a difference, as long as you can access the relevant themes folder. If you're not sure let me know what container image you're using and I'll double check their setup.

@ssddanbrown commented on GitHub (Jun 24, 2022): @AuthorShin Being a docker container should not make too much of a difference, as long as you can access the relevant `themes` folder. If you're not sure let me know what container image you're using and I'll double check their setup.
Author
Owner

@AuthorShin commented on GitHub (Jun 27, 2022):

@ssddanbrown I'm using lscr.io/linuxserver/bookstack:latest image.
I setup the themes folder and also added the functions.php file also added APP_THEME=custom to Environment Variables of the container but if I setup a custom permission on a shelve and the BookStack will deny the access to it if I'm not logged in but even by adding my public IP address to the functions.php file, I couldn't still access it when I open the BookStack with that public IP address when I'm not logged in.

@AuthorShin commented on GitHub (Jun 27, 2022): @ssddanbrown I'm using `lscr.io/linuxserver/bookstack:latest` image. I setup the `themes` folder and also added the `functions.php` file also added `APP_THEME=custom` to Environment Variables of the container but if I setup a custom permission on a shelve and the BookStack will deny the access to it if I'm not logged in but even by adding my public IP address to the `functions.php` file, I couldn't still access it when I open the BookStack with that public IP address when I'm not logged in.
Author
Owner

@ssddanbrown commented on GitHub (Jun 27, 2022):

@AuthorShin It sounds like the functions.php theme file is just not being used.

I setup the themes folder

How/where did you set this up?
For the versions of the linuxserver/bookstack image that support the themes folder, the themes folder should already exist at www/themes within your mounted volume targeting /config in the container.
What version of BookStack are you using? It may be you're currently still using an older container image.
It's since a mid-march image using BookStack v22.02.3 that themes have been supported with linuxserver.io.

@ssddanbrown commented on GitHub (Jun 27, 2022): @AuthorShin It sounds like the `functions.php` theme file is just not being used. > I setup the themes folder How/where did you set this up? For the versions of the linuxserver/bookstack image that support the themes folder, the `themes` folder should already exist at `www/themes` within your mounted volume targeting `/config` in the container. What version of BookStack are you using? It may be you're currently still using an older container image. It's since a [mid-march image using BookStack v22.02.3](https://github.com/linuxserver/docker-bookstack/releases/tag/v22.02.3-ls6) that themes have been supported with linuxserver.io.
Author
Owner

@AuthorShin commented on GitHub (Jun 27, 2022):

I had v22.04.2 now I updated it to the latest version v22.06.1.

How/where did you set this up?
Here which is on casaOS:

And about functions.php file it's in the exact path that you mentioned ( www/themes/custom/functions.php ).

@AuthorShin commented on GitHub (Jun 27, 2022): I had `v22.04.2` now I updated it to the latest version `v22.06.1`. > How/where did you set this up? Here which is on casaOS: <img src="https://i.ibb.co/gT4QXM9/Screenshot-2022-06-27-193411.png"> And about `functions.php` file it's in the exact path that you mentioned ( `www/themes/custom/functions.php` ).
Author
Owner

@AuthorShin commented on GitHub (Jun 27, 2022):

@ssddanbrown
www/themes/custom/functions.php or www/themes/functions.php ?
I used www/themes/custom/functions.php .

@AuthorShin commented on GitHub (Jun 27, 2022): @ssddanbrown `www/themes/custom/functions.php` or `www/themes/functions.php` ? I used `www/themes/custom/functions.php` .
Author
Owner

@AuthorShin commented on GitHub (Jun 27, 2022):

Should I change ID=3 in the following?

    $userIdsByIp = [
        'MyPublicAddress' => 3,
    ]; 
@AuthorShin commented on GitHub (Jun 27, 2022): Should I change ID=`3` in the following? ```php $userIdsByIp = [ 'MyPublicAddress' => 3, ]; ```
Author
Owner

@ssddanbrown commented on GitHub (Jun 27, 2022):

www/themes/custom/functions.php is correct.

Should I change ID=3 in the following?

Yeah, the number should be the ID of the user you want to be logged in for that IP address.
The user ID can be found in the URL when editing a user as an admin.

@ssddanbrown commented on GitHub (Jun 27, 2022): `www/themes/custom/functions.php` is correct. > Should I change ID=3 in the following? Yeah, the number should be the ID of the user you want to be logged in for that IP address. The user ID can be found in the URL when editing a user as an admin.
Author
Owner

@AuthorShin commented on GitHub (Jun 27, 2022):

And there is another question which is unrelated.
Isn't custom permissions suppose to limit access to that shelve/book that we apply them to and the books/pages that they contain?
For example I add custom permissions on a shelve named Debra and within that we have 2 books named Work and Home which each containing a lot of chapters and pages. the shelve (Debra) access is limited and I cannot be accessed without logging in but on 'My Recently Viewed' and 'Recently Updated Pages' those pages and books with show up and if I click on them they will be open.
Actually just the shelve page itself is limited not anything inside it.

@AuthorShin commented on GitHub (Jun 27, 2022): And there is another question which is unrelated. Isn't custom permissions suppose to limit access to that shelve/book that we apply them to and the books/pages that they contain? For example I add custom permissions on a shelve named Debra and within that we have 2 books named Work and Home which each containing a lot of chapters and pages. the shelve (Debra) access is limited and I cannot be accessed without logging in but on 'My Recently Viewed' and 'Recently Updated Pages' those pages and books with show up and if I click on them they will be open. Actually just the shelve page itself is limited not anything inside it.
Author
Owner

@ssddanbrown commented on GitHub (Jun 27, 2022):

Isn't custom permissions suppose to limit access to that shelve/book that we apply them to and the books/pages that they contain?

This is detailed in our docs here:
https://www.bookstackapp.com/docs/user/roles-and-permissions/#content-level-permissions

Specifically:

  • Custom permissions applied to books or chapters will auto-cascade to all child content within, unless that content has its own custom permissions.
  • Custom permissions applied to shelves will not auto-cascade, due to the many-to-many relation to books, but they can be copied to all child books in a single action where required.

This is also mentioned as a warning message when applying shelf custom permissions.

@ssddanbrown commented on GitHub (Jun 27, 2022): > Isn't custom permissions suppose to limit access to that shelve/book that we apply them to and the books/pages that they contain? This is detailed in our docs here: https://www.bookstackapp.com/docs/user/roles-and-permissions/#content-level-permissions Specifically: > - Custom permissions applied to books or chapters will auto-cascade to all child content within, unless that content has its own custom permissions. > - Custom permissions applied to shelves will not auto-cascade, due to the many-to-many relation to books, but they can be copied to all child books in a single action where required. This is also mentioned as a warning message when applying shelf custom permissions.
Author
Owner

@AuthorShin commented on GitHub (Jun 27, 2022):

www/themes/custom/functions.php is correct.

Should I change ID=3 in the following?

Yeah, the number should be the ID of the user you want to be logged in for that IP address. The user ID can be found in the URL when editing a user as an admin.

@ssddanbrown
I even created a new user with ID 3 and set custom permission on that shelve for that user but still not working.

@AuthorShin commented on GitHub (Jun 27, 2022): > `www/themes/custom/functions.php` is correct. > > > Should I change ID=3 in the following? > > Yeah, the number should be the ID of the user you want to be logged in for that IP address. The user ID can be found in the URL when editing a user as an admin. @ssddanbrown I even created a new user with ID 3 and set custom permission on that shelve for that user but still not working.
Author
Owner

@ssddanbrown commented on GitHub (Jun 27, 2022):

@AuthorShin Are you testing while still logged in?

@ssddanbrown commented on GitHub (Jun 27, 2022): @AuthorShin Are you testing while still logged in?
Author
Owner

@AuthorShin commented on GitHub (Jun 27, 2022):

Why logged in? The whole idea is to access it with specific IP without the need to login.

@AuthorShin commented on GitHub (Jun 27, 2022): Why logged in? The whole idea is to access it with specific IP without the need to login.
Author
Owner

@ssddanbrown commented on GitHub (Jun 27, 2022):

@AuthorShin I was just making sure, in case you were expecting to re-log-you-in as another user.

Maybe the logic is not running at all, Could you made the below change temporarily (Adding the dd( line)? This should break BookStack display and show a message instead. If not then the theme system is not running.

// BEFORE
Theme::listen(ThemeEvents::WEB_MIDDLEWARE_BEFORE, function (Request $request) {

// AFTER
Theme::listen(ThemeEvents::WEB_MIDDLEWARE_BEFORE, function (Request $request) {
    dd('This is working!');
@ssddanbrown commented on GitHub (Jun 27, 2022): @AuthorShin I was just making sure, in case you were expecting to re-log-you-in as another user. Maybe the logic is not running at all, Could you made the below change temporarily (Adding the `dd(` line)? This should break BookStack display and show a message instead. If not then the theme system is not running. ```php // BEFORE Theme::listen(ThemeEvents::WEB_MIDDLEWARE_BEFORE, function (Request $request) { // AFTER Theme::listen(ThemeEvents::WEB_MIDDLEWARE_BEFORE, function (Request $request) { dd('This is working!'); ```
Author
Owner

@AuthorShin commented on GitHub (Jun 27, 2022):

@ssddanbrown
So to clarify the situation and the steps:

  1. I add www/themes/custom/functions.php
  2. add data to it
  3. add the public IP address
  4. changed the user ID to 3 (for user test)
  5. add APP_THEME=custom and restart the container
@AuthorShin commented on GitHub (Jun 27, 2022): @ssddanbrown So to clarify the situation and the steps: 1. I add `www/themes/custom/functions.php` 2. add data to it 3. add the public IP address 4. changed the user ID to 3 (for user test) 5. add `APP_THEME=custom` and restart the container <img src="https://i.ibb.co/nr3rQms/Screenshot-2022-06-27-214129.png" > <img src="https://i.ibb.co/khHFjMQ/Screenshot-2022-06-27-214208.png" >
Author
Owner

@AuthorShin commented on GitHub (Jun 27, 2022):

@AuthorShin I was just making sure, in case you were expecting to re-log-you-in as another user.

Maybe the logic is not running at all, Could you made the below change temporarily (Adding the dd( line)? This should break BookStack display and show a message instead. If not then the theme system is not running.

// BEFORE
Theme::listen(ThemeEvents::WEB_MIDDLEWARE_BEFORE, function (Request $request) {

// AFTER
Theme::listen(ThemeEvents::WEB_MIDDLEWARE_BEFORE, function (Request $request) {
    dd('This is working!');

This is my functions.php file right now:

<?php

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

// Register a new web-middleware-before hook to authenticate as a specific user depending
// on IP address. Takes a request and always returns null to indicate we don't want to
// change the response provided back to the user.
Theme::listen(ThemeEvents::WEB_MIDDLEWARE_BEFORE, function (Request $request) {
    dd('This is working!');
    // A mapping of IP addresses to system user IDs.
    // You can add multiple entries here to map many IPs to user accounts.
    // In this example, requests coming from the IP '127.0.0.1' will be logged
    // in as the user with an ID of '3' in the database.
    $userIdsByIp = [
        '152.228.154.20' => 3,
    ];

    // A list of path prefixes we want to ignore to allow some normal auth activities (e.g. Login)
    $ignorePathsPrefixes = ['login', 'register', 'password'];

    // Gather the path and IP of the current request
    $path = $request->path();
    $ip = $request->ip();

    // Track whether the request is allowed for our auto-ip-login logic based upon checking
    // the request path against the above $ignorePathsPrefixes
    $autoLoginPath = true;
    foreach ($ignorePathsPrefixes as $pathPrefix) {
        if (strpos($path, $pathPrefix) === 0) {
            $autoLoginPath = false;
        }
    }

    // If we're already logged-in, don't attempt any login logic and quit out early.
    // If the path is not an auto-login path, and they're using an auto-login IP,
    // log the user out to allow access to normal login functions if desired.
    if (auth()->check()) {
        if (isset($userIdsByIp[$ip]) && !$autoLoginPath) {
            auth()->logout();
        }
        return null;
    }

    // If the current IP address is in our '$userIdsByIp' mapping, and if the path is
    // an auto-login path, look-up the user and log them in. This will force a
    // failure if the user ID is not found in the system.
    if (isset($userIdsByIp[$ip]) && $autoLoginPath) {
        $userId = $userIdsByIp[$ip];
        $user = User::query()->findOrFail($userId);
        auth()->login($user);
    }

    return null;
});
@AuthorShin commented on GitHub (Jun 27, 2022): > @AuthorShin I was just making sure, in case you were expecting to re-log-you-in as another user. > > Maybe the logic is not running at all, Could you made the below change temporarily (Adding the `dd(` line)? This should break BookStack display and show a message instead. If not then the theme system is not running. > > ``` > // BEFORE > Theme::listen(ThemeEvents::WEB_MIDDLEWARE_BEFORE, function (Request $request) { > > // AFTER > Theme::listen(ThemeEvents::WEB_MIDDLEWARE_BEFORE, function (Request $request) { > dd('This is working!'); > ``` This is my `functions.php` file right now: ```php <?php use BookStack\Auth\User; use BookStack\Facades\Theme; use BookStack\Theming\ThemeEvents; use Illuminate\Http\Request; // Register a new web-middleware-before hook to authenticate as a specific user depending // on IP address. Takes a request and always returns null to indicate we don't want to // change the response provided back to the user. Theme::listen(ThemeEvents::WEB_MIDDLEWARE_BEFORE, function (Request $request) { dd('This is working!'); // A mapping of IP addresses to system user IDs. // You can add multiple entries here to map many IPs to user accounts. // In this example, requests coming from the IP '127.0.0.1' will be logged // in as the user with an ID of '3' in the database. $userIdsByIp = [ '152.228.154.20' => 3, ]; // A list of path prefixes we want to ignore to allow some normal auth activities (e.g. Login) $ignorePathsPrefixes = ['login', 'register', 'password']; // Gather the path and IP of the current request $path = $request->path(); $ip = $request->ip(); // Track whether the request is allowed for our auto-ip-login logic based upon checking // the request path against the above $ignorePathsPrefixes $autoLoginPath = true; foreach ($ignorePathsPrefixes as $pathPrefix) { if (strpos($path, $pathPrefix) === 0) { $autoLoginPath = false; } } // If we're already logged-in, don't attempt any login logic and quit out early. // If the path is not an auto-login path, and they're using an auto-login IP, // log the user out to allow access to normal login functions if desired. if (auth()->check()) { if (isset($userIdsByIp[$ip]) && !$autoLoginPath) { auth()->logout(); } return null; } // If the current IP address is in our '$userIdsByIp' mapping, and if the path is // an auto-login path, look-up the user and log them in. This will force a // failure if the user ID is not found in the system. if (isset($userIdsByIp[$ip]) && $autoLoginPath) { $userId = $userIdsByIp[$ip]; $user = User::query()->findOrFail($userId); auth()->login($user); } return null; }); ```
Author
Owner

@AuthorShin commented on GitHub (Jun 27, 2022):

@ssddanbrown
After adding dd things are still working. (php file is above)

@AuthorShin commented on GitHub (Jun 27, 2022): @ssddanbrown After adding `dd` things are still working. (php file is above)
Author
Owner

@AuthorShin commented on GitHub (Jun 27, 2022):

Even with having the functions.php file like this things are still working:

<?php

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

// Register a new web-middleware-before hook to authenticate as a specific user depending
// on IP address. Takes a request and always returns null to indicate we don't want to
// change the response provided back to the user.
Theme::listen(ThemeEvents::WEB_MIDDLEWARE_BEFORE, function (Request $request) {
    dd('This is working!');
});
@AuthorShin commented on GitHub (Jun 27, 2022): Even with having the `functions.php` file like this things are still working: ```php <?php use BookStack\Auth\User; use BookStack\Facades\Theme; use BookStack\Theming\ThemeEvents; use Illuminate\Http\Request; // Register a new web-middleware-before hook to authenticate as a specific user depending // on IP address. Takes a request and always returns null to indicate we don't want to // change the response provided back to the user. Theme::listen(ThemeEvents::WEB_MIDDLEWARE_BEFORE, function (Request $request) { dd('This is working!'); }); ```
Author
Owner

@ssddanbrown commented on GitHub (Jun 27, 2022):

After adding dd things are still working. (php file is above)

Then the theme folder is likely not being read.

Just to confirm, Is www/themes/custom/functions.php part of the folder that's passed to your BookStack contained as a mounted volume to /config? Does the same www folder contain a .env file and uploads directory?

@ssddanbrown commented on GitHub (Jun 27, 2022): > After adding dd things are still working. (php file is above) Then the theme folder is likely not being read. Just to confirm, Is `www/themes/custom/functions.php` part of the folder that's passed to your BookStack contained as a mounted volume to `/config`? Does the same `www` folder contain a `.env` file and `uploads` directory?
Author
Owner

@AuthorShin commented on GitHub (Jun 27, 2022):

Just to confirm, Is www/themes/custom/functions.php part of the folder that's passed to your BookStack contained as a mounted volume to /config? Does the same www folder contain a .env file and uploads directory?

@ssddanbrown
Yes it is.
And there are .env file and uploads directory inside that www folder but I didn't add APP_THEME=custom to that .env file, I add it to the container Environment Variables as that's how in casaOS works.
As shown here:
https://github.com/BookStackApp/BookStack/issues/3464#issuecomment-1167472105

@AuthorShin commented on GitHub (Jun 27, 2022): > Just to confirm, Is `www/themes/custom/functions.php` part of the folder that's passed to your BookStack contained as a mounted volume to `/config`? Does the same `www` folder contain a `.env` file and `uploads` directory? @ssddanbrown Yes it is. And there are `.env` file and `uploads` directory inside that `www` folder but I didn't add `APP_THEME=custom` to that `.env` file, I add it to the container Environment Variables as that's how in casaOS works. As shown here: https://github.com/BookStackApp/BookStack/issues/3464#issuecomment-1167472105
Author
Owner

@ssddanbrown commented on GitHub (Jun 27, 2022):

Gotta admit, I'm running out of ideas, there's something preventing the themes folder from being used. Possible extra steps:

  • You could try adding the APP_THEME option to the www/.env file (And removing any options of the same name if they exist).
  • Double check that the actual container is running from the latest image, and that you haven't just updated the base image without updating the container itself.
@ssddanbrown commented on GitHub (Jun 27, 2022): Gotta admit, I'm running out of ideas, there's something preventing the themes folder from being used. Possible extra steps: - You could try adding the `APP_THEME` option to the `www/.env` file (And removing any options of the same name if they exist). - Double check that the actual container is running from the latest image, and that you haven't just updated the base image without updating the container itself.
Author
Owner

@AuthorShin commented on GitHub (Jun 27, 2022):

I added that to the www/.env file but no change.
In settings of BookStack the version is shown like this:

Is it correct?

@AuthorShin commented on GitHub (Jun 27, 2022): I added that to the `www/.env` file but no change. In settings of BookStack the version is shown like this: <img src="https://i.ibb.co/9s8hhSX/Screenshot-2022-06-27-222209.png" > Is it correct?
Author
Owner

@ssddanbrown commented on GitHub (Jun 27, 2022):

Yeah, that appears correct.

I just started up a fresh docker-compose setup, using the docker-compose config shown in their readme, just to double check this can be done using their image. Everything seemed to work as expected, themes folder was exposed as expected.

To replicate things any further I feel I'd need to create a CasaOS setup.

@ssddanbrown commented on GitHub (Jun 27, 2022): Yeah, that appears correct. I just started up a fresh docker-compose setup, using the docker-compose config shown in their readme, just to double check this can be done using their image. Everything seemed to work as expected, themes folder was exposed as expected. To replicate things any further I feel I'd need to create a CasaOS setup.
Author
Owner

@AuthorShin commented on GitHub (Jun 27, 2022):

@ssddanbrown
Thanks for all the time and energy that you're putting in.
For casaOS you have to have BookStack container and MariaDB separated.
You can use this .json files to import via casaOS and install the easily.
BookStack:

{"origin":"custom","network_model":"bridge","index":"/","icon":"https://cdn.jsdelivr.net/gh/IceWhaleTech/AppIcon@main/all/bookstack.png","image":"lscr.io/linuxserver/bookstack:latest","envs":[{"container":"PUID","host":"1000","desc":"","type":0},{"container":"PGID","host":"1000","desc":"","type":0},{"container":"APP_URL","host":"https://bookstack.local","desc":"","type":0},{"container":"DB_HOST","host":"MariaDBinternaLIPaddress","desc":"","type":0},{"container":"DB_USER","host":"bookstack","desc":"","type":0},{"container":"DB_PASS","host":"YourMYSQL_PASSWORDfromMariaDB","desc":"","type":0},{"container":"DB_DATABASE","host":"bookstackapp","desc":"","type":0},{"container":"APP_THEME","host":"custom","desc":"","type":0}],"ports":[{"container":"80","host":"6875","protocol":"tcp","desc":"","type":0}],"volumes":[{"container":"/config","host":"/home/docker/bookstack/data","type":0,"desc":""}],"devices":[],"port_map":"6875","cpu_shares":10,"restart":"always","enable_upnp":false,"label":"BookStack","description":"","position":true,"host_name":"","privileged":false,"cap_add":[],"cmd":[],"version":"1.0"}

MariaDB:

{"origin":"custom","network_model":"bridge","index":"","icon":"https://cdn.jsdelivr.net/gh/IceWhaleTech/AppIcon@main/all/mariadb.png","image":"lscr.io/linuxserver/mariadb:latest","envs":[{"container":"PUID","host":"1000","desc":"","type":0},{"container":"PGID","host":"1000","desc":"","type":0},{"container":"MYSQL_ROOT_PASSWORD","host":"YourMYSQL_ROOT_PASSWORD","desc":"","type":0},{"container":"TZ","host":"Europe/London","desc":"","type":0},{"container":"MYSQL_DATABASE","host":"bookstackapp","desc":"","type":0},{"container":"MYSQL_USER","host":"bookstack","desc":"","type":0},{"container":"MYSQL_PASSWORD","host":"YourMYSQL_PASSWORD","desc":"","type":0}],"ports":[{"container":"3306","host":"3316","protocol":"tcp","desc":"","type":0}],"volumes":[{"container":"/config","host":"/home/docker/bookstack/database","type":0,"desc":""}],"devices":[],"port_map":"","cpu_shares":10,"restart":"always","enable_upnp":false,"label":"BookStackDB","description":"","position":true,"host_name":"","privileged":false,"cap_add":[],"cmd":[],"version":"1.0"}
@AuthorShin commented on GitHub (Jun 27, 2022): @ssddanbrown Thanks for all the time and energy that you're putting in. For casaOS you have to have BookStack container and MariaDB separated. You can use this .json files to import via casaOS and install the easily. BookStack: ```json {"origin":"custom","network_model":"bridge","index":"/","icon":"https://cdn.jsdelivr.net/gh/IceWhaleTech/AppIcon@main/all/bookstack.png","image":"lscr.io/linuxserver/bookstack:latest","envs":[{"container":"PUID","host":"1000","desc":"","type":0},{"container":"PGID","host":"1000","desc":"","type":0},{"container":"APP_URL","host":"https://bookstack.local","desc":"","type":0},{"container":"DB_HOST","host":"MariaDBinternaLIPaddress","desc":"","type":0},{"container":"DB_USER","host":"bookstack","desc":"","type":0},{"container":"DB_PASS","host":"YourMYSQL_PASSWORDfromMariaDB","desc":"","type":0},{"container":"DB_DATABASE","host":"bookstackapp","desc":"","type":0},{"container":"APP_THEME","host":"custom","desc":"","type":0}],"ports":[{"container":"80","host":"6875","protocol":"tcp","desc":"","type":0}],"volumes":[{"container":"/config","host":"/home/docker/bookstack/data","type":0,"desc":""}],"devices":[],"port_map":"6875","cpu_shares":10,"restart":"always","enable_upnp":false,"label":"BookStack","description":"","position":true,"host_name":"","privileged":false,"cap_add":[],"cmd":[],"version":"1.0"} ``` MariaDB: ```json {"origin":"custom","network_model":"bridge","index":"","icon":"https://cdn.jsdelivr.net/gh/IceWhaleTech/AppIcon@main/all/mariadb.png","image":"lscr.io/linuxserver/mariadb:latest","envs":[{"container":"PUID","host":"1000","desc":"","type":0},{"container":"PGID","host":"1000","desc":"","type":0},{"container":"MYSQL_ROOT_PASSWORD","host":"YourMYSQL_ROOT_PASSWORD","desc":"","type":0},{"container":"TZ","host":"Europe/London","desc":"","type":0},{"container":"MYSQL_DATABASE","host":"bookstackapp","desc":"","type":0},{"container":"MYSQL_USER","host":"bookstack","desc":"","type":0},{"container":"MYSQL_PASSWORD","host":"YourMYSQL_PASSWORD","desc":"","type":0}],"ports":[{"container":"3306","host":"3316","protocol":"tcp","desc":"","type":0}],"volumes":[{"container":"/config","host":"/home/docker/bookstack/database","type":0,"desc":""}],"devices":[],"port_map":"","cpu_shares":10,"restart":"always","enable_upnp":false,"label":"BookStackDB","description":"","position":true,"host_name":"","privileged":false,"cap_add":[],"cmd":[],"version":"1.0"} ```
Author
Owner

@ssddanbrown commented on GitHub (Jun 29, 2022):

Okay, have now done a run-though testing this with a fresh CasaOS setup on a fresh Ubuntu 22.04 install.
I used the configs you provide (thanks!) and only tweaked the password fields, APP_URL option and DB_HOST options.
I left all volume paths as-is.
After getting a running BookStack setup on CasaOS, I uploaded a functions.php in the location shown below:

image

This worked as expected, with first the simplified debug version of functions.php causing the displayed output, then with the full IP address to user mapping. Within the paths shown, the themes folder already existed, I did create the custom folder myself. I also restarted my BookStack container after mapping and this continued to work.

I did experience a bug within CasaOS, where using the file upload tool in the file browser, to upload a smaller file over a larger existing file, would only overwrite the larger file for the length of the new smaller file, effectively producing a bad merge of the two files. This caused invalid PHP in my case which could lead to a white blank screen upon BookStack access.

  • Do my paths exactly align with yours?
  • What was your method of creating the theme folder and files? I did this within the CasaOS file browser.
  • What is the output of running ls -alh /home/docker/bookstack/data/www/themes/custom/ on the host system? Mine is as follows:
ls -alh /home/docker/bookstack/data/www/themes/custom/
total 12K
drwxrwxr-x 2 dan dan 4.0K Jun 29 10:38 .
drwxrwxr-x 3 dan dan 4.0K Jun 29 10:24 ..
-rw-rw-r-- 1 dan dan  464 Jun 29 10:38 functions.php

I was suprised to see CasaOS use my own system user (dan) for permissions here.
I'm just wondering if file/folder permissions could be getting in the way here if the bookstack container processes don't have the ability to access the themes folder or functions file.

@ssddanbrown commented on GitHub (Jun 29, 2022): Okay, have now done a run-though testing this with a fresh CasaOS setup on a fresh Ubuntu 22.04 install. I used the configs you provide (thanks!) and only tweaked the password fields, APP_URL option and DB_HOST options. I left all volume paths as-is. After getting a running BookStack setup on CasaOS, I uploaded a `functions.php` in the location shown below: ![image](https://user-images.githubusercontent.com/8343178/176415718-16afb2bf-da58-49b1-8c16-d6c04c6ab246.png) This worked as expected, with first the simplified debug version of `functions.php` causing the displayed output, then with the full IP address to user mapping. Within the paths shown, the `themes` folder already existed, I did create the `custom` folder myself. I also restarted my BookStack container after mapping and this continued to work. I did experience a bug within CasaOS, where using the file upload tool in the file browser, to upload a smaller file over a larger existing file, would only overwrite the larger file for the length of the new smaller file, effectively producing a bad merge of the two files. This caused invalid PHP in my case which could lead to a white blank screen upon BookStack access. - Do my paths exactly align with yours? - What was your method of creating the theme folder and files? I did this within the CasaOS file browser. - What is the output of running `ls -alh /home/docker/bookstack/data/www/themes/custom/` on the host system? Mine is as follows: ``` ls -alh /home/docker/bookstack/data/www/themes/custom/ total 12K drwxrwxr-x 2 dan dan 4.0K Jun 29 10:38 . drwxrwxr-x 3 dan dan 4.0K Jun 29 10:24 .. -rw-rw-r-- 1 dan dan 464 Jun 29 10:38 functions.php ``` I was suprised to see CasaOS use my own system user (`dan`) for permissions here. I'm just wondering if file/folder permissions could be getting in the way here if the bookstack container processes don't have the ability to access the themes folder or functions file.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/BookStack#2819