@tiddlywiki/mws 0.0.15 → 0.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -34
- package/dist/server.d.ts +20 -9
- package/dist/server.js +3920 -379
- package/dist/server.js.map +1 -1
- package/editions/mws-docs/tiddlers/$__StoryList.tid +1 -3
- package/editions/mws-docs/tiddlers/2025-02-18 - User Management.md +56 -0
- package/editions/mws-docs/tiddlers/2025-02-18 - User Management.md.meta +5 -0
- package/editions/mws-docs/tiddlers/2025-04-03 - Phases of Development.md +64 -0
- package/editions/mws-docs/tiddlers/2025-04-03 - Phases of Development.md.meta +5 -0
- package/editions/mws-docs/tiddlers/2025-04-13 - Plugins.md +18 -0
- package/editions/mws-docs/tiddlers/2025-04-13 - Plugins.md.meta +5 -0
- package/editions/mws-docs/tiddlers/2025-05-04.md +13 -0
- package/editions/mws-docs/tiddlers/2025-05-04.md.meta +5 -0
- package/editions/mws-docs/tiddlers/2025-05-06.md +19 -0
- package/editions/mws-docs/tiddlers/2025-05-06.md.meta +5 -0
- package/editions/mws-docs/tiddlers/Access Control.md +17 -0
- package/editions/mws-docs/tiddlers/Access Control.md.meta +5 -0
- package/editions/mws-docs/tiddlers/Application Access & Security.md +98 -0
- package/editions/mws-docs/tiddlers/Application Access & Security.md.meta +5 -0
- package/editions/mws-docs/tiddlers/Checklists and Features.md +15 -0
- package/editions/mws-docs/tiddlers/Checklists and Features.md.meta +5 -0
- package/editions/mws-docs/tiddlers/HTTP API.md +17 -0
- package/editions/mws-docs/tiddlers/HTTP API.md.meta +5 -0
- package/editions/mws-docs/tiddlers/Installation.tid +11 -2
- package/editions/mws-docs/tiddlers/MWS Architecture.md +15 -0
- package/editions/mws-docs/tiddlers/MWS Architecture.md.meta +5 -0
- package/editions/mws-docs/tiddlers/Moduler Design.md +5 -0
- package/editions/mws-docs/tiddlers/Moduler Design.md.meta +1 -1
- package/editions/mws-docs/tiddlers/Notes.tid +5 -0
- package/editions/mws-docs/tiddlers/Reference.md +0 -149
- package/editions/mws-docs/tiddlers/Reference.md.meta +4 -1
- package/editions/mws-docs/tiddlers/Usage.tid +3 -3
- package/editions/mws-docs/tiddlers/system/$__palettes_MUI-Dark +173 -0
- package/editions/mws-docs/tiddlers/system/$__palettes_MUI-Dark.meta +6 -0
- package/editions/mws-docs/tiddlers/system/$__palettes_MUI-Light +172 -0
- package/editions/mws-docs/tiddlers/system/$__palettes_MUI-Light.meta +6 -0
- package/package.json +11 -20
- package/plugins/client/tiddlers/readme.tid +0 -3
- package/react-user-mgmt/public/main.js +32 -32
- package/react-user-mgmt/public/main.js.map +4 -4
- package/react-user-mgmt/public/stats.json +1 -1
- package/scripts.mjs +34 -0
- package/.env-cmdrc +0 -5
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
Described here is a full blown role-based identity & access management system. However we are unlikely to need this level of sophistication immediately.
|
|
2
|
+
|
|
3
|
+
## Logical groupings and definitions
|
|
4
|
+
|
|
5
|
+
- A user is a logical grouping of logins.
|
|
6
|
+
- An organization ("content space") is a logical grouping of users and the content they interact with.
|
|
7
|
+
- The organization owner is a user who sets the privileges other users have in the organization.
|
|
8
|
+
- If enabled, every user is the owner of their own personal organization.
|
|
9
|
+
- If enabled, they may own extra organizations.
|
|
10
|
+
- The organization owner has all privileges in the organization except those they explicitly deny themself.
|
|
11
|
+
- They cannot deny themself the ability to change privileges in the organization.
|
|
12
|
+
- They may delegate to managers.
|
|
13
|
+
- Admins are users with site-wide privileges.
|
|
14
|
+
- The admin role is separate from the owner role. They are not site-wide owners.
|
|
15
|
+
- Admins can take various actions on extra orginizations, depending on site settings.
|
|
16
|
+
- Admins can manage users access to the site and take related actions.
|
|
17
|
+
- Depending on settings, admins cannot view content that does not belong to them, unless shared (the exact privacy details here aren't important, it's the technical features that I'm including this for).
|
|
18
|
+
- Site admins can define a public content space which everyone can view, and an additional content space which authenticated users can view. These act as implicit organizations with admins given permissions as managers.
|
|
19
|
+
|
|
20
|
+
Even though it sounds like I'm expecting this to be some kind of public document sharing platform or online collaboration, the setup actually has multiple use-cases within a single organization that are just as complicated.
|
|
21
|
+
|
|
22
|
+
### To recap the various roles in an organization
|
|
23
|
+
|
|
24
|
+
- **admin** - Granted site-wide permissions.
|
|
25
|
+
- **owner** - Granted organization level permissions.
|
|
26
|
+
- **manager** - Delegated permission from owners.
|
|
27
|
+
- **user** - Explicitly invited and added to the organization user list by owners or managers.
|
|
28
|
+
- **auth** - Visitor signed in and not in the user list.
|
|
29
|
+
- **anon** - Visitor not signed into the site.
|
|
30
|
+
|
|
31
|
+
### There are two permission levels within the wiki
|
|
32
|
+
|
|
33
|
+
- **writer** - can edit tiddlers, optionally filtered
|
|
34
|
+
- **reader** - can view tiddlers, optionally filtered
|
|
35
|
+
|
|
36
|
+
Owners can create permission profiles which define reader and writer filters, then assign them to users or groups (or to their access to a specific wiki), and when they update the permission profile the changes apply everywhere.
|
|
37
|
+
|
|
38
|
+
I mean look, at some point I'm just implementing an entire Identity Access Management service.
|
|
39
|
+
|
|
40
|
+
## JSON settings file
|
|
41
|
+
|
|
42
|
+
A short list of options in a JSON file alongside the database (or with the database settings) which determines some permanent settings that depend on the use case.
|
|
43
|
+
|
|
44
|
+
- Whether admins can change user email address or oauth identity and set user passwords (account takeover).
|
|
45
|
+
- Whether admins can view site content unrestricted (account privacy).
|
|
46
|
+
- Sets the max visibility owners and admins can set (since that shouldn't need to change).
|
|
47
|
+
- The default default visibility (before orgs change it).
|
|
48
|
+
|
|
49
|
+
### settings for content spaces (organizations)
|
|
50
|
+
|
|
51
|
+
- Whether new users get their own personal content space (personal organization).
|
|
52
|
+
- Whether non-admin users can be given additional content spaces (extra organizations).
|
|
53
|
+
- Whether non-admin users can create their own additional content spaces (extra organizations).
|
|
54
|
+
- Whether additional content spaces created by non-admin users can be removed from them by admins (this will depend on the use case).
|
|
55
|
+
|
|
56
|
+
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
Welcome to the MultiWikiServer wiki!
|
|
2
|
+
|
|
3
|
+
## Phases of development
|
|
4
|
+
|
|
5
|
+
### Phase 1 is to get a fully working system that can be extended.
|
|
6
|
+
|
|
7
|
+
The features here should cover all of the core requirements.
|
|
8
|
+
|
|
9
|
+
- Database fully async and concurrent with transactions and row locking.
|
|
10
|
+
- Recipes and bags fully supported.
|
|
11
|
+
- Support for both server-wide (wiki-like) and per-user (doc-like) recipes.
|
|
12
|
+
- Shadow bags to hold each user's drafts and customizations for server-wide or shared recipes.
|
|
13
|
+
- Possible integration of various tiddler namespace behaviors, like private `User:{username}` tiddlers.
|
|
14
|
+
- Option *on the server* for users to propose edits to existing tiddlers, probably by moving a tiddler to a different bag.
|
|
15
|
+
- The concept of multiple users fully supported. Auth state has a userID property.
|
|
16
|
+
- Auth with username and password by default, but allowing custom integrations to be built that use third-party auth libraries or services. Several of us already have different ideas in mind, and we need to build all the required mechanisms in phase 1 in order to make sure we're properly supporting them, even if we don't actually support the third-party integrations themselves until phase 2.
|
|
17
|
+
- Multiple sessions editing the same wiki supported *by the server*, with revision mechanisms to prevent overwriting edits with an old version.
|
|
18
|
+
- Sharing read or write access with other users via invite links.
|
|
19
|
+
|
|
20
|
+
### Phase 2 is to add all the other important features
|
|
21
|
+
|
|
22
|
+
- [Full integration with popular auth solutions.](https://github.com/TiddlyWiki/MultiWikiServer/issues/1)
|
|
23
|
+
- [Full Identity & Access Management support.](https://github.com/TiddlyWiki/MultiWikiServer/wiki/User-Management-3)
|
|
24
|
+
- Collaborative editing sessions.
|
|
25
|
+
|
|
26
|
+
## How the server classes work together
|
|
27
|
+
|
|
28
|
+
This implements a server that abstracts the various HTTP protocols into a single request state object which it then hands out to the routes.
|
|
29
|
+
|
|
30
|
+
- **Streamer** abstracts away the difference between HTTP/1.1 and HTTP/2 to allow both to be handled transparently.
|
|
31
|
+
- Normalizes the request and response into a single class.
|
|
32
|
+
- Currently it doesn't support push streams, but we could change that.
|
|
33
|
+
- **Listeners** handle the server listener and send requests they recieve to the router.
|
|
34
|
+
- ListenerHTTP: Sets up and handles HTTP requests using the http module.
|
|
35
|
+
- ListenerHTTPS: Sets up and handles HTTPS requests using the http2 module (with http1.1 support).
|
|
36
|
+
- **Router**: The main server instance. Handles route matching and sets up a state object for each request. It also instantiates subsystems.
|
|
37
|
+
- **AuthState** (subsystem): Contains all authentication logic and is called at various points in the request process. It may throw to abort the request.
|
|
38
|
+
- **StateObject**: Contains everything routes have access to, including a database connection. Subsystems may create their own state classes which take the StateObject as a constructor argument.
|
|
39
|
+
|
|
40
|
+
## Thoughts on routing
|
|
41
|
+
|
|
42
|
+
Routing generally works well, but the current routes are all strictly path based. They mix various concerns into one module based on path similarities.
|
|
43
|
+
|
|
44
|
+
I think it would be a lot more streamlined to separate the concerns into different sections. Each of those would operate as their own submodule.
|
|
45
|
+
|
|
46
|
+
Why? Because this is how complicated permissions can get:
|
|
47
|
+
|
|
48
|
+
- **Auth** determines who the user is.
|
|
49
|
+
- Auth adapters that connect third-party auth services, with fields like profile pic, display name, email, etc.
|
|
50
|
+
- Auth strategies like session cookies or access tokens.
|
|
51
|
+
- Login and registration forms, email and phone interactions, etc.
|
|
52
|
+
- **Users** contains all the code for changing what the user is allowed to do.
|
|
53
|
+
- List of users, with tabs for pending, roles, etc.
|
|
54
|
+
- Handle user registrations and initial setup.
|
|
55
|
+
- Manage sharing and collaboration permissions: [Roles](https://github.com/Arlen22/TW5-MWS/wiki/Roles) (eventually)
|
|
56
|
+
- **Recipes** shows the user their available recipes and lets them create or modify.
|
|
57
|
+
- (Phase 1): Users create their own recipes and bags and specify read/write permissions for those recipes and bags.
|
|
58
|
+
- (Phase 2): Admins can define scoped bags which are added to recipes based on the user's role.
|
|
59
|
+
- **Wikis** contains all the code that runs when accessing the wiki itself.
|
|
60
|
+
- Tiddler saving and loading based on the recipe instructions.
|
|
61
|
+
- Uploads and other third-party integrations requiring server support.
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
We need the MWS server to be as modular as possible. Obviously certain things, like the route implementations, are difficult to make modular. But various sections are much more self-contained, or interact with the rest of the codebase in a small, well-defined way, and these can be turned into pluggable services.
|
|
3
|
+
|
|
4
|
+
Server routes for various sections of the UI can be kept separate, so the recipe/bag manger, user manager, and actual wiki routes can be put in separate modules so that one of them can easily be rewritten without affecting the others.
|
|
5
|
+
|
|
6
|
+
All of them interact with the database via the prisma adapter, which can be modified to handle different databases. We should support mariadb, sqlite, and postgresql to cover the main ones. Making sure the prisma client covers all three is probably important. There may be small differences between the prisma client for different database types, although this will be reflected in the types, so we should be able to figure that out pretty easily.
|
|
7
|
+
|
|
8
|
+
The attachment store isn't something I've taken a close look at.
|
|
9
|
+
|
|
10
|
+
The tiddlywiki instance on the server might stay. At this point I don't think we actually need it for anything besides rendering the index wiki. That might be moved to the start command instead of being part of the mws runtime. But it's also used for various import and export commands which still need to be available on the cli. We could make loading optional, or unload it after commands have completed, or once mws-listen starts.
|
|
11
|
+
|
|
12
|
+
I don't think things are quite where they should be with the client either. Currently we're adding recipe tiddlers into the wiki page dynamically, which is expected, but there are like six tiddlers that are being rendered statically, which doesn't really make sense. It also doesn't make sense that we're dumping some plugins into the database but rendering core from tiddlywiki, since this results in a version mismatch.
|
|
13
|
+
|
|
14
|
+
At the same time, we really don't want to be rendering plugins every time. They do need to be cached somewhere so they can be loaded quickly. I wonder if it would work to cache them in the wiki folder, per tiddlywiki version, so if you upgrade it would just create a new folder. The boot tiddlers would be cached in the folder as well. If we do it right, we wouldn't even have to parse the file, just read it onto the wire. We'd probably need an index file to keep everything straight. We could add plugins/themes/languages support to the wiki folder as well, which would also get cached in the same way. We could make a way for caching to be disabled, perhaps by adding a field to `plugin.info`.
|
|
15
|
+
|
|
16
|
+
It would be useful if the plugin syntax could specify NPM modules. We already have the `+` and `++` syntax. I'm not sure exactly how it'd work, but the NPM package would need to determine it's own path, which is fairly simple, and then export that so it can be imported via the standard import mechanism. Obviously the package would need to be installed, and it should probably be imported into the run file and then added as an absolute path to the list of imports. Actually, I guess that's already possible, so I just need to add the list of imports part of it.
|
|
17
|
+
|
|
18
|
+
-- Arlen22
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
We need a way to add hooks at most significant points of the process. Maybe all code should just be hooks. Plugins need to be able to hook in and change what they need. I'm still trying to figure out how to put all the pieces together.
|
|
2
|
+
|
|
3
|
+
I want routes to call the register function, rather than being called by setup code. But then I have to figure out where to put the register functions.
|
|
4
|
+
|
|
5
|
+
Plugins need to hook into a whole bunch of points in the setup process, but they aren't bootstrapped until after the database is connected.
|
|
6
|
+
|
|
7
|
+
I think the biggest problem is that I was originally planning to architect it with everything in the config file (similar to how a build system or server works), but it seems everyone wants to use the UI and store config in the database as much as possible, so I'll probably end up with something a lot more like WordPress. Once I rearrange everything more logically using imports, it should be fairly obvious how to use plugins.
|
|
8
|
+
|
|
9
|
+
I probably need a startup state object, which basically has the site config and `rootRoute`. I also need to setup the CLI listen command [as outlined here](https://talk.tiddlywiki.org/t/mws-how-simple-can-we-make-the-cli-for-mws/12460).
|
|
10
|
+
|
|
11
|
+
I guess this is actually a significant rewrite, so once I get some of the initial pieces done, it should be more obvious.
|
|
12
|
+
|
|
13
|
+
-- Arlen22
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
There have been several different posts complaining about the long wait times when importing huge volumes of tiddlers. I took a look at the syncer and syncadaptor this evening, and realized that most of this is caused by the designed of the syncer itself, not the syncadaptor. The syncer only saves tiddlers one at a time. There's no batching. I'm not even sure if there is an option for batching.
|
|
2
|
+
|
|
3
|
+
It's probably going to be a good idea to redesign the syncer from the ground up. The syncer hooks directly into the change events on the wiki. From there it calculates which tiddlers need to be synced. I think it would be good to get as close to the wiki as possible, so hooking directly into the change events is probably a good idea.
|
|
4
|
+
|
|
5
|
+
For the purposes of MWS, the syncer is actually pretty basic, and most of the features are probably not used, however, the syncer presents a standard API surface between the UI internals and the sync adapter. If I can modify it to handle more bulk updates, that would help.
|
|
6
|
+
|
|
7
|
+
I think the syncer also needs to be updated to be more aware of the recipe. Being able to understand the recipe is kind of important in understanding how to deal with deletions efficiently. It needs to be aware of read-only tiddlers.
|
|
8
|
+
|
|
9
|
+
Speaking of recipes, I keep bouncing this idea around in my mind of recipes which are multi-layered. Each level of the recipe could be opened by admins in order to easily make changes to the bag without creating a separate recipe. You can't just edit an individual bag because you need the bags below it in order to make sense out of it.
|
|
10
|
+
|
|
11
|
+
There also isn't a good way to move tiddlers between levels. Admins will need to be given some extra tools to do this with.
|
|
12
|
+
|
|
13
|
+
I'm not good at wikitext, but I can provide the endpoints for all of these operations as well as the client-side adapters and actions to use them.
|
|
14
|
+
|
|
15
|
+
I also don't know why we aren't using the wiki mount point for the API, and putting the react UI under admin, since then it would free up the entire path space to use for a tree path structure.
|
|
16
|
+
|
|
17
|
+
I'm working on simplifying the internal code structure yet again, still focusing on getting everything up to speed with my latest ideas.
|
|
18
|
+
|
|
19
|
+
-- Arlen22
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Access Control is implemented separately for both recipes and bags, but bags can inherit the ACL of recipes they are added to.
|
|
2
|
+
|
|
3
|
+
### Permission Inheritance
|
|
4
|
+
- Users receive combined permissions from all assigned roles
|
|
5
|
+
- When roles grant different permission levels for the same resource, the higher access level is granted. For example, if one role grants "read" and another grants "write" access to a recipe, the user receives "write" access since it includes all lower-level permissions. If a role grants "admin", it inherits both "read" and "write".
|
|
6
|
+
|
|
7
|
+
### "Readonly" permission
|
|
8
|
+
|
|
9
|
+
If this were reversed, and users with explicit "read" access were forbidden from writing, it would significantly complicate roles.
|
|
10
|
+
|
|
11
|
+
Imagine a group of engineers working on several projects. Each project has people who are responsible for editing the documentation for everyone else. So everyone needs to be granted the read permission on all projects, but only a few people are granted the write permission on each project.
|
|
12
|
+
|
|
13
|
+
The easiest approach is to maintain one role which grants "read" access to all users, and then maintain additional roles to grant "write" access to the users responsible for each project.
|
|
14
|
+
|
|
15
|
+
If granting read access explicitly prevented a user from writing, we would need to create two roles for each project, one which which grants write access for the project, and another which grants read access to all other projects.
|
|
16
|
+
|
|
17
|
+
Every time a new project is added, all other projects would need to grant "read" access to that new "all projects but one" role on every single wiki for every single project in the entire organization.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
|
|
2
|
+
Users can be administered through two interfaces:
|
|
3
|
+
|
|
4
|
+
1. Web-based Administrative Interface
|
|
5
|
+
- Accessible to all users.
|
|
6
|
+
- Provides graphical interface for user operations
|
|
7
|
+
- Real-time validation and feedback
|
|
8
|
+
1. Command-line Interface (CLI) Tools
|
|
9
|
+
- Only available to server owner.
|
|
10
|
+
- Suitable for automation and scripting
|
|
11
|
+
- Enables batch operations
|
|
12
|
+
- Useful for system initialization
|
|
13
|
+
|
|
14
|
+
Each user account contains the following essential components:
|
|
15
|
+
|
|
16
|
+
- **Username**
|
|
17
|
+
- Must be unique across the system
|
|
18
|
+
- Case-sensitive
|
|
19
|
+
- Used for authentication and audit trails
|
|
20
|
+
- **Password**
|
|
21
|
+
- Stored using secure hashing algorithms
|
|
22
|
+
- Never stored in plaintext
|
|
23
|
+
- Subject to complexity requirements
|
|
24
|
+
- **Email**
|
|
25
|
+
- Eventually used for the obvious password reset.
|
|
26
|
+
- **Role Assignments**
|
|
27
|
+
- Multiple roles can be assigned
|
|
28
|
+
- Inherited permissions from all assigned roles
|
|
29
|
+
- Dynamic permission calculation based on role combination
|
|
30
|
+
|
|
31
|
+
## Access Levels
|
|
32
|
+
|
|
33
|
+
Conceptually, there are 6 access levels.
|
|
34
|
+
|
|
35
|
+
- **Site owner** - has file system access to the server, and can run CLI commands. Presumably they also have a site admin account.
|
|
36
|
+
- **Site admin** - Users with the admin *role*. They can assign owners and change permissions, and have full read and write access. Most ACL checks are skipped for the admin role.
|
|
37
|
+
- **Entity owner** - Users who "own" an entity (bag or recipe). They can change permissions for that entity, and have full read and write access. *Entity admins* cannot change the owner.
|
|
38
|
+
- **Entity admin** - Users granted the admin *permission* on an entity. They cannot change the owner, but they can change the permissions of other users for that entity.
|
|
39
|
+
- **Entity write** - Users granted the write *permission* on an enitity. They can list, read, create, update, and delete tiddlers, but cannot change permissions.
|
|
40
|
+
- **Entity read** - Users granted the read *permission* on an entity. They can list and read tiddlers, but cannot do anything else.
|
|
41
|
+
|
|
42
|
+
## Entities
|
|
43
|
+
|
|
44
|
+
- **Bag** - A collection of tiddlers with unique titles
|
|
45
|
+
- **Recipe** - A stack of bags in a specific order. Bags may inherit the ACL of a recipe they are included in.
|
|
46
|
+
|
|
47
|
+
## Roles
|
|
48
|
+
|
|
49
|
+
- Roles have names and descriptions
|
|
50
|
+
- Multiple users can be assigned to a role
|
|
51
|
+
|
|
52
|
+
## Permissions
|
|
53
|
+
|
|
54
|
+
- **READ** - Read tiddlers from an entity.
|
|
55
|
+
- **WRITE** - Write tiddlers to an entity.
|
|
56
|
+
- **ADMIN** - Update ACL for an entity.
|
|
57
|
+
|
|
58
|
+
## Admin
|
|
59
|
+
|
|
60
|
+
- There is an admin *role* and an admin *permission*.
|
|
61
|
+
- Roles are given specific permissions for specific entities (bags and recipes).
|
|
62
|
+
- The admin *role* has automatic admin *permission* for everything.
|
|
63
|
+
|
|
64
|
+
## ACL
|
|
65
|
+
|
|
66
|
+
- Grants the **Permission** for an **Entity** to a **Role**.
|
|
67
|
+
- Entities without an ACL are either public or private (configurable).
|
|
68
|
+
|
|
69
|
+
## Ownership
|
|
70
|
+
|
|
71
|
+
- Ownership of an entity grants the "admin" *permission*.
|
|
72
|
+
- Only site admins can change the owner of an entity.
|
|
73
|
+
- Users with "admin" *permission* **cannot** change ownership.
|
|
74
|
+
|
|
75
|
+
## User Types
|
|
76
|
+
|
|
77
|
+
#### Administrator (ADMIN) Role
|
|
78
|
+
|
|
79
|
+
- Full system access and configuration rights
|
|
80
|
+
- Most access checks are skipped
|
|
81
|
+
- Can create, modify, and delete user accounts
|
|
82
|
+
- Manages role assignments and permissions
|
|
83
|
+
- Has full permissions on all recipes and bags
|
|
84
|
+
|
|
85
|
+
#### Regular Users
|
|
86
|
+
|
|
87
|
+
- Created by administrators
|
|
88
|
+
- Permissions determined by assigned roles
|
|
89
|
+
- Access limited to specific recipes based on role permissions
|
|
90
|
+
- Access to recipes without an ACL is based on recipe config
|
|
91
|
+
|
|
92
|
+
#### Guest Users
|
|
93
|
+
|
|
94
|
+
- Users not logged in.
|
|
95
|
+
- No inherent permissions
|
|
96
|
+
- Can access recipes which allow it
|
|
97
|
+
- Read/write can be enabled by server config
|
|
98
|
+
- Useful for public wikis or documentation sites
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
## ACL
|
|
2
|
+
|
|
3
|
+
- Verify that anonymous users only have the access defined by allowAnon.
|
|
4
|
+
- No access to owned bags.
|
|
5
|
+
- No access to bags with ACL defined.
|
|
6
|
+
- Verify that logged in users only have the access expected
|
|
7
|
+
- No access to bags owned by other users.
|
|
8
|
+
- Unless they are in the ACL for the bag.
|
|
9
|
+
- No more access than what is granted by the ACL.
|
|
10
|
+
- Verify that all admin permissions are based on the admin role, not the first user.
|
|
11
|
+
- Verify that admin's cannot remove the admin role from themselves.
|
|
12
|
+
|
|
13
|
+
## Recipes
|
|
14
|
+
|
|
15
|
+
-
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
The MultiWikiServer HTTP API provides management and tiddler endpoints.
|
|
2
|
+
|
|
3
|
+
The design goals of the API are:
|
|
4
|
+
|
|
5
|
+
- Connect the client and server as transparently as possible.
|
|
6
|
+
- Be easy to understand and use via Javascript.
|
|
7
|
+
- Have strict validation of incoming requests.
|
|
8
|
+
|
|
9
|
+
## Management
|
|
10
|
+
|
|
11
|
+
- On the client, most request paths are defined by a single adaptor function which accepts the input for the server and returns a promise which resolves to the server's parsed response.
|
|
12
|
+
- The server may throw a user error (or a string), which is expected to return to the client. It should give them an actionable understanding of what went wrong.
|
|
13
|
+
- The API essentially forwards a function call from the client to the server, using `fetch`. It expects a Javascript client, and is not intended to support form submissions directly.
|
|
14
|
+
|
|
15
|
+
## Tiddler
|
|
16
|
+
|
|
17
|
+
The tiddler API was based on [the API of TiddlyWeb](https://tank.peermore.com/tanks/tiddlyweb/HTTP%20API), first developed in 2008 by Chris Dent, but is more oriented around JSON and Typescript. The concept of resources remains and in the future it will hopefully be adapted to serve static versions of tiddlers.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
created: 20241105133737778
|
|
2
|
-
modified:
|
|
2
|
+
modified: 20250428144159846
|
|
3
3
|
tags: TableOfContents
|
|
4
4
|
title: Installation
|
|
5
5
|
type: text/vnd.tiddlywiki
|
|
@@ -20,5 +20,14 @@ See [[Troubleshooting]] if you encounter any errors.
|
|
|
20
20
|
To update your copy of MWS in the future with newer changes will require re-downloading the code, taking care not to lose any changes you might have made.
|
|
21
21
|
|
|
22
22
|
# Make a backup: Copy or zip your project folder to a safe backup folder. <<.copy-code-to-clipboard "tar -cf archive.tar my_folder">>
|
|
23
|
-
# Get the latest version. Notice that the second word is `install` instead of `init`. This pulls the latest version from NPM and installs it. <<.copy-code-to-clipboard "npm install @tiddlywiki/mws@latest">>
|
|
23
|
+
# Get the latest version. Notice that the second word is `install` instead of `init`. This pulls the latest version from NPM and installs it. <<.copy-code-to-clipboard "npm install @tiddlywiki/mws@latest --save-exact">>
|
|
24
24
|
# Start the server. On startup, MWS checks the database schema and updates it automatically if there are changes. Normally this works just fine, but it can fail, which is why it's important to save a backup first. <<.copy-code-to-clipboard "npm start">>
|
|
25
|
+
|
|
26
|
+
!!! Git repo
|
|
27
|
+
|
|
28
|
+
It is optionally recommended to save a history of your project configuration using git.
|
|
29
|
+
|
|
30
|
+
* On Windows you can use [[GitHub Desktop|https://github.com/apps/desktop]].
|
|
31
|
+
* On Linux, git is usually preinstalled or available via the default package manager for your distro.
|
|
32
|
+
|
|
33
|
+
If you decide to do this, you should move the wiki folder out of the project folder, and change the `wikiPath` setting accordingly.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
### Features
|
|
2
|
+
|
|
3
|
+
* Bag & Recipe system for storing tiddlers.
|
|
4
|
+
* User and Role management with ACL.
|
|
5
|
+
* Attachment system for storing binary tiddlers on the file system.
|
|
6
|
+
* Various import and export commands (currently still in development).
|
|
7
|
+
|
|
8
|
+
### Planned (hopefully) for the future
|
|
9
|
+
|
|
10
|
+
* AuthJS or a similar integration that supports third-party OAuth (you can already write your own).
|
|
11
|
+
* Compiling filters to SQL to optimize memory on both the client and server.
|
|
12
|
+
* Support for other database and storage systems. Most likely MariaDB and Postgres.
|
|
13
|
+
* Additional recipe strategies with features like prefixed bags and namespaces.
|
|
14
|
+
* Server rendering of pages, for a more wikipedia-like experience.
|
|
15
|
+
* Some kind of plugin system which provides a level of server-side access into the request path
|
|
@@ -22,3 +22,8 @@
|
|
|
22
22
|
|
|
23
23
|
- Maps route definitions into service handlers
|
|
24
24
|
- HTTP, Websockets
|
|
25
|
+
|
|
26
|
+
### Database Connector
|
|
27
|
+
- Prisma handles query translation (wasm or native addon)
|
|
28
|
+
- Prisma supports custom adapters, and also provides standard ones
|
|
29
|
+
- Connector classes in MWS take care of database setup and schema updates
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
# Authentication & Authorization
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
Our application has transitioned from a conventional username/password authentication system to a more robust Authentication and Authorization implementation. This new system supports multiple user accounts, roles, permissions, and a comprehensive access control list.
|
|
6
|
-
|
|
7
|
-
## Key Features
|
|
8
|
-
|
|
9
|
-
1. Multiple User Accounts
|
|
10
|
-
1. Role-based Access Control
|
|
11
|
-
1. Granular Permissions
|
|
12
|
-
1. Access Control List (ACL)
|
|
13
|
-
|
|
14
|
-
## Application Access & Security
|
|
15
|
-
|
|
16
|
-
### Access Levels
|
|
17
|
-
|
|
18
|
-
Conceptually, there are 6 access levels.
|
|
19
|
-
|
|
20
|
-
- **Site owner** - has file system access to the server, and can run CLI commands. Presumably they also have a site admin account.
|
|
21
|
-
- **Site admin** - Users with the admin *role*. They can assign owners and change permissions, and have full read and write access.
|
|
22
|
-
- **Entity owner** - Users who "own" an entity (bag or recipe). They can change permissions for that entity, and have full read and write access.
|
|
23
|
-
- **Entity admin** - Users granted the admin *permission* on an entity. They cannot change the owner, but they can change the permissions of other users for that entity.
|
|
24
|
-
- **Entity write** - Users granted the write *permission* on an enitity. They can list, read, create, update, and delete tiddlers, but cannot change permissions.
|
|
25
|
-
- **Entity read** - Users granted the read *permission* on an entity. They can list and read tiddlers, but cannot do anything else.
|
|
26
|
-
|
|
27
|
-
### Initial Setup
|
|
28
|
-
|
|
29
|
-
When you first launch the Multiwiki Server, it creates a default admin user. The username is `admin` and the password is `1234`. To secure your installation you should change this immediately.
|
|
30
|
-
|
|
31
|
-
### Entities
|
|
32
|
-
|
|
33
|
-
- **Bag** - A collection of tiddlers with unique titles
|
|
34
|
-
- **Recipe** - A stack of bags in a specific order. Bags may inherit the ACL of a recipe they are included in.
|
|
35
|
-
|
|
36
|
-
### Roles
|
|
37
|
-
|
|
38
|
-
- Roles have names and descriptions
|
|
39
|
-
- Multiple users can be assigned to a role
|
|
40
|
-
|
|
41
|
-
### Permissions
|
|
42
|
-
|
|
43
|
-
- **READ** - Read tiddlers from an entity.
|
|
44
|
-
- **WRITE** - Write tiddlers to an entity.
|
|
45
|
-
- **ADMIN** - Update ACL for an entity.
|
|
46
|
-
|
|
47
|
-
### ACL
|
|
48
|
-
|
|
49
|
-
- Grants the **Permission** for an **Entity** to a **Role**.
|
|
50
|
-
- Entities without an ACL are either public or private (configurable).
|
|
51
|
-
|
|
52
|
-
### Ownership
|
|
53
|
-
|
|
54
|
-
- Ownership of an entity grants the "admin" *permission*.
|
|
55
|
-
- Only site admins can change the owner of an entity.
|
|
56
|
-
- Users with "admin" *permission* **cannot** change ownership.
|
|
57
|
-
|
|
58
|
-
### User Types
|
|
59
|
-
|
|
60
|
-
#### Administrator (ADMIN) Role
|
|
61
|
-
|
|
62
|
-
- Full system access and configuration rights
|
|
63
|
-
- Most access checks are skipped
|
|
64
|
-
- Can create, modify, and delete user accounts
|
|
65
|
-
- Manages role assignments and permissions
|
|
66
|
-
- Has full permissions on all recipes and bags
|
|
67
|
-
|
|
68
|
-
#### Regular Users
|
|
69
|
-
|
|
70
|
-
- Created by administrators
|
|
71
|
-
- Permissions determined by assigned roles
|
|
72
|
-
- Access limited to specific recipes based on role permissions
|
|
73
|
-
- Access to recipes without an ACL is based on recipe config
|
|
74
|
-
|
|
75
|
-
#### Guest Users
|
|
76
|
-
|
|
77
|
-
- Users not logged in.
|
|
78
|
-
- No inherent permissions
|
|
79
|
-
- Can access recipes which allow it
|
|
80
|
-
- Read/write can be enabled by server config
|
|
81
|
-
- Useful for public wikis or documentation sites
|
|
82
|
-
|
|
83
|
-
### Access Control
|
|
84
|
-
|
|
85
|
-
Access Control is implemented separately for both recipes and bags, but bags can in inherit the ACL of recipes they are added to.
|
|
86
|
-
|
|
87
|
-
#### Permission Inheritance
|
|
88
|
-
- Users receive combined permissions from all assigned roles
|
|
89
|
-
- When roles grant different permission levels for the same resource, the higher access level is granted. For example, if one role grants "read" and another grants "write" access to a recipe, the user receives "write" access since it includes all lower-level permissions.
|
|
90
|
-
|
|
91
|
-
If this were reversed, and users with explicit "read" access were forbidden from writing, it would significantly complicate roles.
|
|
92
|
-
|
|
93
|
-
Imagine a group of engineers working on several projects. Each project has people who are responsible for editing the documentation for everyone else. So everyone needs to be granted the read permission on all projects, but only a few people are granted the write permission on each project.
|
|
94
|
-
|
|
95
|
-
The easiest approach is to maintain one role which grants "read" access to all users, and then maintain additional roles to grant "write" access to the users responsible for each project.
|
|
96
|
-
|
|
97
|
-
If granting read access explicitly prevented a user from writing, we would need to create two roles for each project, one which which grants write access for the project, and another which grants read access to all other projects.
|
|
98
|
-
|
|
99
|
-
Every time a new project is added, all other projects would need to grant "read" access to that new "all projects but one" role on every single wiki for every single project in the entire organization.
|
|
100
|
-
|
|
101
|
-
## User Management & Security Architecture
|
|
102
|
-
|
|
103
|
-
### User Account Management
|
|
104
|
-
|
|
105
|
-
Users can be administered through two interfaces:
|
|
106
|
-
|
|
107
|
-
1. Web-based Administrative Interface
|
|
108
|
-
- Accessible to all users.
|
|
109
|
-
- Provides graphical interface for user operations
|
|
110
|
-
- Real-time validation and feedback
|
|
111
|
-
1. Command-line Interface (CLI) Tools
|
|
112
|
-
- Only available to server owner.
|
|
113
|
-
- Suitable for automation and scripting
|
|
114
|
-
- Enables batch operations
|
|
115
|
-
- Useful for system initialization
|
|
116
|
-
|
|
117
|
-
Each user account contains the following essential components:
|
|
118
|
-
|
|
119
|
-
- **Username**
|
|
120
|
-
- Must be unique across the system
|
|
121
|
-
- Case-sensitive
|
|
122
|
-
- Used for authentication and audit trails
|
|
123
|
-
- **Password**
|
|
124
|
-
- Stored using secure hashing algorithms
|
|
125
|
-
- Never stored in plaintext
|
|
126
|
-
- Subject to complexity requirements
|
|
127
|
-
- **Email**
|
|
128
|
-
- Eventually used for the obvious password reset.
|
|
129
|
-
- **Role Assignments**
|
|
130
|
-
- Multiple roles can be assigned
|
|
131
|
-
- Inherited permissions from all assigned roles
|
|
132
|
-
- Dynamic permission calculation based on role combination
|
|
133
|
-
|
|
134
|
-
# HTTP API
|
|
135
|
-
|
|
136
|
-
The MultiWikiServer HTTP API provides management and tiddler endpoints. It was based on [the API of TiddlyWeb](https://tank.peermore.com/tanks/tiddlyweb/HTTP%20API), first developed in 2008 by Chris Dent, but is more oriented around JSON and Typescript.
|
|
137
|
-
|
|
138
|
-
The design goals of the API are:
|
|
139
|
-
|
|
140
|
-
- Connect the client and server as transparently as possible.
|
|
141
|
-
- Follow the principles of remote procedure calls.
|
|
142
|
-
- Be easy to understand and use via Javascript.
|
|
143
|
-
- Have strict validation of incoming requests.
|
|
144
|
-
|
|
145
|
-
General points about the design:
|
|
146
|
-
|
|
147
|
-
- On the client, most request paths are defined by a single adaptor function which accepts the input for the server and returns a promise which resolves to the server's parsed response.
|
|
148
|
-
- The server may throw a user error, which is expected to return to the client. It should give them an actionable understanding of what went wrong.
|
|
149
|
-
|