|
1 | | -# Website |
| 1 | +# Protected docs |
2 | 2 |
|
3 | | -This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator. |
| 3 | +This is an example on how to restrict access to a documentation website written with [`docusaurus`](https://docusaurus.io/). |
4 | 4 |
|
5 | | -### Installation |
| 5 | +## Details |
6 | 6 |
|
7 | | -``` |
8 | | -$ yarn |
9 | | -``` |
10 | | - |
11 | | -### Local Development |
12 | | - |
13 | | -``` |
14 | | -$ yarn start |
15 | | -``` |
| 7 | +The implementation uses vercels ["middleware"](./middleware.ts) to check each request for the correct authentication data. For user management and authentication, a [`PocketBase`](https://pocketbase.io/) instance is used. |
16 | 8 |
|
17 | | -This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. |
| 9 | +## Considerations |
18 | 10 |
|
19 | | -### Build |
| 11 | +It is important to note that at least with `docusaurus`, one cannot protect individual routes. This is because once one route has been opened, `docusaurus` behaves like a SPA and greedily loads all the content into the client. No way to disentangle that js-blob. |
20 | 12 |
|
21 | | -``` |
22 | | -$ yarn build |
23 | | -``` |
24 | | - |
25 | | -This command generates static content into the `build` directory and can be served using any static contents hosting service. |
| 13 | +In this implementation, anybody can sign up and then immediately see the content. That is kinda pointless of course. It is possible to check for roles or attributes on the users. For example one could adjust the middleware like so: |
26 | 14 |
|
27 | | -### Deployment |
| 15 | +```typescript |
| 16 | +// middleware.ts |
| 17 | +import PocketBase from "pocketbase"; |
| 18 | +import { next, rewrite } from "@vercel/edge"; |
28 | 19 |
|
29 | | -Using SSH: |
| 20 | +export const config = { |
| 21 | + matcher: ["/", "/((?!public/|api/).*)"], |
| 22 | +}; |
30 | 23 |
|
31 | | -``` |
32 | | -$ USE_SSH=true yarn deploy |
| 24 | +export default async function authentication(request: Request) { |
| 25 | + const pb = new PocketBase("https://levinkeller.de"); |
| 26 | + const cookie = request.headers.get("cookie"); |
| 27 | + if (!cookie) return rewrite("/public/login.html"); |
| 28 | + pb.authStore.loadFromCookie(cookie); |
| 29 | + try { |
| 30 | + await pb.collection("users").authRefresh(); |
| 31 | + if (pb.authStore.model?.member) { |
| 32 | + return next(); |
| 33 | + } else { |
| 34 | + // not_a_member.html shows instructions on how to reach the admin to make the person a member. |
| 35 | + return rewrite("/public/not_a_member.html"); |
| 36 | + } |
| 37 | + } catch { |
| 38 | + return rewrite("/public/login.html"); |
| 39 | + } |
| 40 | +} |
33 | 41 | ``` |
34 | 42 |
|
35 | | -Not using SSH: |
| 43 | +Then only users whos accounts are made a "member" after creation could access the website.**Please be aware that this only is secure, iff you make sure that users cannot make themselves "members" [by using `@request.data.member:isset = false` in the appropriate API rules](https://github.com/pocketbase/pocketbase/discussions/5486#discussioncomment-10556948)!** |
36 | 44 |
|
37 | | -``` |
38 | | -$ GIT_USER=<Your GitHub username> yarn deploy |
39 | | -``` |
| 45 | +## Run it yourself |
40 | 46 |
|
41 | | -If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. |
| 47 | +In order to run this yourself, you need to host a `PocketBase` instance and then fork this repo and adjust the values. Deployment needs to happen via vercel. I assume it also works on netlify or coolify with some minor adjustments. |
0 commit comments