mbkauthe 5.0.0 → 5.0.2
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/LICENSE +161 -335
- package/README.md +98 -112
- package/docs/README.md +33 -0
- package/docs/STYLE.md +40 -0
- package/docs/diagrams/auth-processes.mmd +80 -0
- package/docs/{env.md → guides/configuration.md} +2 -1
- package/docs/{db.md → guides/database.md} +3 -1
- package/docs/images/auth-processes.svg +1 -0
- package/docs/reference/api/authentication.md +105 -0
- package/docs/{api.md → reference/api/endpoints.md} +2 -683
- package/docs/reference/api/examples.md +251 -0
- package/docs/reference/api/middleware.md +239 -0
- package/docs/reference/api/operations.md +52 -0
- package/docs/reference/api.md +19 -0
- package/docs/{error-messages.md → reference/error-codes.md} +2 -0
- package/lib/createTable.js +2 -2
- package/package.json +4 -3
- package/docs/auth-processes.mmd +0 -71
- package/docs/images/auth-process.svg +0 -1
- /package/docs/{auth-flows.mmd → diagrams/auth-flows.mmd} +0 -0
- /package/docs/{db.sql → schema/db.sql} +0 -0
package/README.md
CHANGED
|
@@ -6,172 +6,158 @@
|
|
|
6
6
|
[](https://github.com/MIbnEKhalid/mbkauthe/actions/workflows/publish.yml)
|
|
7
7
|
[](https://www.npmjs.com/package/mbkauthe)
|
|
8
8
|
|
|
9
|
-
|
|
10
9
|
<p align="center">
|
|
11
10
|
<img height="64px" src="./public/logo.png" alt="MBKAuthe" />
|
|
12
11
|
</p>
|
|
13
12
|
|
|
14
|
-
**MBKAuthe** is an open source
|
|
15
|
-
|
|
16
|
-
> **Note:** MBKAuthe is intentionally limited to authentication and session validation. The full user/permission/dashboard management system is a separate product called **MBKCore**, developed by MBKTech and not currently open source. Access to MBKCore is currently available only to the MBKTech team, and we may refine it and consider open sourcing it in the future.
|
|
13
|
+
**MBKAuthe** is an open source authentication package for Node.js, Express, and PostgreSQL. It handles login, session validation, role/app access checks, optional TOTP 2FA, OAuth login, API token authentication, and multi-session management.
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
- Currently, for every request to a protected page, a database query is made to retrieve authentication information (allowed apps, username, session ID, role, etc.). We should implement a caching mechanism to reduce this overhead, but also find a way to allow administrators to log users out and update permissions in near real-time.
|
|
15
|
+
> **Note:** MBKAuthe is intentionally focused on authentication and session validation. The broader user, permission, and dashboard management system is a separate MBKTech product named **MBKCore**(closed source for now).
|
|
20
16
|
|
|
21
|
-
##
|
|
17
|
+
## Features
|
|
22
18
|
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
- CSRF protection
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
- Dynamic profile picture routing with session caching
|
|
35
|
-
- Modern responsive UI with desktop two-column layout
|
|
36
|
-
- Dev-only DB Query Monitor with callsite, timing, and request context
|
|
19
|
+
- Express middleware for session validation and role checks
|
|
20
|
+
- PostgreSQL-backed user, session, 2FA, trusted-device, and API-token storage
|
|
21
|
+
- Secure password authentication with PBKDF2
|
|
22
|
+
- Optional TOTP 2FA with trusted devices
|
|
23
|
+
- GitHub App and Google OAuth login flows
|
|
24
|
+
- API token authentication with read-only/write scopes
|
|
25
|
+
- Configurable multi-session support per user
|
|
26
|
+
- CSRF protection, rate limiting, secure cookies, and session fixation prevention
|
|
27
|
+
- Customizable Handlebars views
|
|
28
|
+
- Vercel/serverless-friendly deployment support
|
|
29
|
+
- Dev-only DB Query Monitor with callsite, timing, request context, and pool stats
|
|
37
30
|
|
|
38
|
-
##
|
|
31
|
+
## Installation
|
|
39
32
|
|
|
40
33
|
```bash
|
|
41
34
|
npm install mbkauthe
|
|
42
35
|
```
|
|
43
36
|
|
|
44
|
-
##
|
|
37
|
+
## Quick Start
|
|
45
38
|
|
|
46
|
-
|
|
39
|
+
1. Copy the environment template.
|
|
47
40
|
|
|
48
|
-
```
|
|
41
|
+
```powershell
|
|
49
42
|
Copy-Item .env.example .env
|
|
50
43
|
```
|
|
51
|
-
See [docs/env.md](docs/env.md).
|
|
52
44
|
|
|
53
|
-
|
|
54
|
-
Run [docs/db.sql](docs/db.sql) to create tables and a default SuperAdmin (`support` / `12345678`). Change the password immediately. See [docs/db.md](docs/db.md).
|
|
45
|
+
2. Configure environment values.
|
|
55
46
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
```javascript
|
|
59
|
-
import express from 'express';
|
|
60
|
-
import mbkauthe, { sessVal, roleChk } from 'mbkauthe';
|
|
61
|
-
import dotenv from 'dotenv';
|
|
62
|
-
dotenv.config();
|
|
47
|
+
See the [configuration guide](docs/guides/configuration.md) for `mbkautheVar`, `mbkauthShared`, OAuth settings, session settings, and deployment flags.
|
|
63
48
|
|
|
64
|
-
|
|
65
|
-
app.use(mbkauthe);
|
|
49
|
+
3. Create database tables.
|
|
66
50
|
|
|
67
|
-
|
|
68
|
-
app.get('/admin', sessVal, roleChk(['SuperAdmin']), (req, res) => res.send('Admin Panel'));
|
|
69
|
-
|
|
70
|
-
app.listen(3000);
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## 🧪 Testing
|
|
51
|
+
Run [docs/schema/db.sql](docs/schema/db.sql) against PostgreSQL, or use the package script:
|
|
74
52
|
|
|
75
53
|
```bash
|
|
76
|
-
npm
|
|
77
|
-
npm run test:watch
|
|
78
|
-
npm run dev
|
|
54
|
+
npm run create-tables
|
|
79
55
|
```
|
|
80
56
|
|
|
81
|
-
|
|
57
|
+
The schema includes a default SuperAdmin user (`support` / `12345678`). Change that password immediately. See the [database guide](docs/guides/database.md).
|
|
82
58
|
|
|
83
|
-
|
|
84
|
-
- **Role Check:** `checkRolePermission(['Role'])`/`roleChk(['Role'])`
|
|
85
|
-
- **Combined:** `validateSessionAndRole(['SuperAdmin', 'NormalUser'])`/`sessRole(['SuperAdmin', 'NormalUser'])`
|
|
86
|
-
- **API Token Auth:** `authenticate(process.env.API_TOKEN)`
|
|
59
|
+
4. Mount MBKAuthe in Express.
|
|
87
60
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
MBKAuthe treats a request as **JSON** (and returns JSON errors) when any of the following apply:
|
|
93
|
-
|
|
94
|
-
- URL/path starts with `/mbkauthe/api/` or `/api/`
|
|
95
|
-
- `X-Requested-With: XMLHttpRequest`
|
|
96
|
-
- `Accept` indicates JSON (e.g., `application/json`) and does not explicitly prefer `text/html`
|
|
97
|
-
- `User-Agent` looks like a non-browser client (e.g., `curl`, `wget`, `Postman`)
|
|
98
|
-
- `User-Agent: json` (explicitly forces JSON responses)
|
|
61
|
+
```javascript
|
|
62
|
+
import express from "express";
|
|
63
|
+
import dotenv from "dotenv";
|
|
64
|
+
import mbkauthe, { sessVal, roleChk } from "mbkauthe";
|
|
99
65
|
|
|
100
|
-
|
|
101
|
-
```bash
|
|
102
|
-
curl -i -H "User-Agent: json" http://localhost:3000/mbkauthe/test
|
|
103
|
-
```
|
|
66
|
+
dotenv.config();
|
|
104
67
|
|
|
105
|
-
|
|
68
|
+
const app = express();
|
|
106
69
|
|
|
107
|
-
|
|
70
|
+
app.use(mbkauthe);
|
|
108
71
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
72
|
+
app.get("/dashboard", sessVal, (req, res) => {
|
|
73
|
+
res.send(`Welcome ${req.session.user.username}!`);
|
|
74
|
+
});
|
|
112
75
|
|
|
113
|
-
|
|
76
|
+
app.get("/admin", sessVal, roleChk("SuperAdmin"), (req, res) => {
|
|
77
|
+
res.send("Admin Panel");
|
|
78
|
+
});
|
|
114
79
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
- PostgreSQL-backed sessions with automatic cleanup
|
|
118
|
-
- OAuth with state validation and secure callbacks
|
|
80
|
+
app.listen(3000);
|
|
81
|
+
```
|
|
119
82
|
|
|
120
|
-
##
|
|
83
|
+
## Common Exports
|
|
121
84
|
|
|
122
|
-
|
|
85
|
+
- `sessVal` / `validateSession` - require a valid session or API token.
|
|
86
|
+
- `roleChk` / `checkRolePermission` - require a role after session validation.
|
|
87
|
+
- `sessRole` / `validateSessionAndRole` - combine session and role checks.
|
|
88
|
+
- `strictValidateSession` - require cookie session authentication only.
|
|
89
|
+
- `strictValidateSessionAndRole` - strict cookie session plus role check.
|
|
90
|
+
- `authenticate(token)` - protect server-to-server routes with a static bearer token.
|
|
91
|
+
- `dblogin` - access the configured PostgreSQL pool.
|
|
123
92
|
|
|
124
|
-
|
|
93
|
+
See the [API reference](docs/reference/api.md) for endpoints, middleware, examples, security notes, and rate limits.
|
|
125
94
|
|
|
126
|
-
|
|
95
|
+
## JSON Error Responses
|
|
127
96
|
|
|
128
|
-
|
|
97
|
+
Browser page routes usually render HTML errors, while API/AJAX-style requests receive JSON. MBKAuthe treats a request as JSON when any of these are true:
|
|
129
98
|
|
|
130
|
-
-
|
|
131
|
-
-
|
|
132
|
-
-
|
|
99
|
+
- The path starts with `/mbkauthe/api/` or `/api/`
|
|
100
|
+
- `X-Requested-With: XMLHttpRequest`
|
|
101
|
+
- `Accept` prefers JSON and does not explicitly prefer `text/html`
|
|
102
|
+
- `User-Agent` looks like a non-browser client such as `curl`, `wget`, or `Postman`
|
|
103
|
+
- `User-Agent: json`
|
|
133
104
|
|
|
134
|
-
|
|
105
|
+
```bash
|
|
106
|
+
curl -i -H "User-Agent: json" http://localhost:3000/mbkauthe/test
|
|
107
|
+
```
|
|
135
108
|
|
|
136
|
-
|
|
109
|
+
## Development
|
|
137
110
|
|
|
138
|
-
|
|
111
|
+
```bash
|
|
112
|
+
npm test
|
|
113
|
+
npm run test:watch
|
|
114
|
+
npm run dev
|
|
115
|
+
```
|
|
139
116
|
|
|
140
|
-
-
|
|
141
|
-
- **DB Query Monitor (JSON):** `/mbkauthe/db.json`
|
|
142
|
-
- **SuperAdmin check:** `/mbkauthe/debug/validate-superadmin`
|
|
117
|
+
Development-only diagnostics are mounted when `process.env.env === "dev"`:
|
|
143
118
|
|
|
144
|
-
|
|
119
|
+
- `/mbkauthe/db` - DB Query Monitor UI
|
|
120
|
+
- `/mbkauthe/db.json` - DB Query Monitor JSON
|
|
121
|
+
- `/mbkauthe/db/reset` - reset diagnostic query logs
|
|
122
|
+
- `/mbkauthe/validate-superadmin` - SuperAdmin validation check
|
|
145
123
|
|
|
146
|
-
##
|
|
124
|
+
## Documentation
|
|
147
125
|
|
|
148
|
-
|
|
149
|
-
-
|
|
150
|
-
-
|
|
151
|
-
-
|
|
152
|
-
-
|
|
153
|
-
-
|
|
126
|
+
- [Documentation index](docs/README.md)
|
|
127
|
+
- [Configuration guide](docs/guides/configuration.md)
|
|
128
|
+
- [Database guide](docs/guides/database.md)
|
|
129
|
+
- [API reference](docs/reference/api.md)
|
|
130
|
+
- [Authentication and sessions](docs/reference/api/authentication.md)
|
|
131
|
+
- [Endpoints](docs/reference/api/endpoints.md)
|
|
132
|
+
- [Middleware](docs/reference/api/middleware.md)
|
|
133
|
+
- [Code examples](docs/reference/api/examples.md)
|
|
134
|
+
- [Operational reference](docs/reference/api/operations.md)
|
|
135
|
+
- [Error codes](docs/reference/error-codes.md)
|
|
136
|
+
- [Documentation style guide](docs/STYLE.md)
|
|
154
137
|
|
|
155
|
-
|
|
138
|
+
## Deployment Checklist
|
|
156
139
|
|
|
157
|
-
|
|
140
|
+
- Set `IS_DEPLOYED=true`
|
|
141
|
+
- Use strong `SESSION_SECRET_KEY` and `Main_SECRET_TOKEN` values
|
|
142
|
+
- Enable HTTPS
|
|
143
|
+
- Set the correct `DOMAIN`
|
|
144
|
+
- Set an appropriate `COOKIE_EXPIRE_TIME`
|
|
145
|
+
- Store secrets in environment variables
|
|
146
|
+
- Configure OAuth credentials only when the matching provider is enabled
|
|
158
147
|
|
|
159
|
-
|
|
160
|
-
- [Database Schema](docs/db.md)
|
|
161
|
-
- [Environment Config](docs/env.md)
|
|
162
|
-
- [Error Codes](docs/error-messages.md)
|
|
148
|
+
Vercel deployments can use shared OAuth credentials through `mbkauthShared`.
|
|
163
149
|
|
|
164
|
-
##
|
|
150
|
+
## License
|
|
165
151
|
|
|
166
|
-
GPL v2.0
|
|
152
|
+
GPL v2.0 - see [LICENSE](LICENSE).
|
|
167
153
|
|
|
168
|
-
##
|
|
154
|
+
## Author
|
|
169
155
|
|
|
170
156
|
**Muhammad Bin Khalid**
|
|
171
|
-
|
|
172
|
-
|
|
157
|
+
[support@mbktech.org](mailto:support@mbktech.org) | [chmuhammadbinkhalid28@gmail.com](mailto:chmuhammadbinkhalid28@gmail.com)
|
|
158
|
+
[GitHub @MIbnEKhalid](https://github.com/MIbnEKhalid)
|
|
173
159
|
|
|
174
|
-
##
|
|
160
|
+
## Links
|
|
175
161
|
|
|
176
162
|
- [npm](https://www.npmjs.com/package/mbkauthe)
|
|
177
163
|
- [GitHub](https://github.com/MIbnEKhalid/mbkauthe)
|
|
@@ -179,4 +165,4 @@ GPL v2.0 — see [LICENSE](LICENSE)
|
|
|
179
165
|
|
|
180
166
|
---
|
|
181
167
|
|
|
182
|
-
Made with
|
|
168
|
+
Made with love by [MBKTech.org](https://mbktech.org).
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# MBKAuthe Documentation
|
|
2
|
+
|
|
3
|
+
This directory is organized by how the documentation is used:
|
|
4
|
+
|
|
5
|
+
- **Guides** - setup and operational walkthroughs.
|
|
6
|
+
- **Reference** - detailed API and error-code documentation.
|
|
7
|
+
- **Schema** - executable database SQL.
|
|
8
|
+
- **Diagrams** - Mermaid source files and rendered images.
|
|
9
|
+
|
|
10
|
+
## Start here
|
|
11
|
+
|
|
12
|
+
- [Project README](../README.md)
|
|
13
|
+
- [Configuration guide](guides/configuration.md)
|
|
14
|
+
- [Database guide](guides/database.md)
|
|
15
|
+
- [API reference](reference/api.md)
|
|
16
|
+
- [Error codes](reference/error-codes.md)
|
|
17
|
+
- [Documentation style guide](STYLE.md)
|
|
18
|
+
|
|
19
|
+
## Source layout
|
|
20
|
+
|
|
21
|
+
- `guides/` - task-oriented setup and operations docs.
|
|
22
|
+
- `reference/` - detailed facts, route lists, middleware details, and error-code documentation.
|
|
23
|
+
- `reference/api/` - split API reference sections included from the API index.
|
|
24
|
+
- `schema/` - executable SQL and schema assets.
|
|
25
|
+
- `diagrams/` - Mermaid source files.
|
|
26
|
+
- `images/` - rendered diagram outputs and documentation images.
|
|
27
|
+
|
|
28
|
+
## Assets
|
|
29
|
+
|
|
30
|
+
- [Database schema SQL](schema/db.sql)
|
|
31
|
+
- [Authentication flow Mermaid source](diagrams/auth-flows.mmd)
|
|
32
|
+
- [Authentication process Mermaid source](diagrams/auth-processes.mmd)
|
|
33
|
+
- [Rendered diagram images](images/)
|
package/docs/STYLE.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Documentation Style Guide
|
|
2
|
+
|
|
3
|
+
[Back to docs index](README.md) | [Back to project README](../README.md)
|
|
4
|
+
|
|
5
|
+
Use this guide when adding or changing documentation source.
|
|
6
|
+
|
|
7
|
+
## File Placement
|
|
8
|
+
|
|
9
|
+
- Put setup walkthroughs and operational how-to content in `guides/`.
|
|
10
|
+
- Put endpoint, middleware, type, and error-code details in `reference/`.
|
|
11
|
+
- Put long API sections under `reference/api/` and link them from `reference/api.md`.
|
|
12
|
+
- Put executable database SQL in `schema/`.
|
|
13
|
+
- Put Mermaid source in `diagrams/` and rendered outputs in `images/`.
|
|
14
|
+
|
|
15
|
+
## Markdown Structure
|
|
16
|
+
|
|
17
|
+
- Use one `#` title per file.
|
|
18
|
+
- Keep files focused on one job; split a file when it becomes hard to scan or review.
|
|
19
|
+
- Add a small navigation line under the title for files below `docs/`.
|
|
20
|
+
- Prefer descriptive links such as `[Configuration guide](guides/configuration.md)` over raw paths in prose.
|
|
21
|
+
- Keep table-of-contents blocks short; rely on smaller files instead of very deep TOCs.
|
|
22
|
+
|
|
23
|
+
## Code Blocks
|
|
24
|
+
|
|
25
|
+
- Always include a language tag when the language is known: `javascript`, `json`, `bash`, `sql`, `env`, or `typescript`.
|
|
26
|
+
- Keep examples copy-pasteable where possible.
|
|
27
|
+
- Use placeholders for secrets and tokens; never include real credentials.
|
|
28
|
+
- Keep endpoint examples close to the endpoint they describe.
|
|
29
|
+
|
|
30
|
+
## Cross-Links
|
|
31
|
+
|
|
32
|
+
- Links from `docs/README.md` are relative to `docs/`.
|
|
33
|
+
- Links from `docs/reference/api/*.md` need one extra `..` segment to reach the docs index.
|
|
34
|
+
- After moving docs, run a Markdown link check before committing.
|
|
35
|
+
|
|
36
|
+
## Generated Assets
|
|
37
|
+
|
|
38
|
+
- Mermaid source is authoritative.
|
|
39
|
+
- Rendered images in `images/` should be regenerated when the matching `.mmd` file changes.
|
|
40
|
+
- Keep package scripts aligned with the source paths in `diagrams/`.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
sequenceDiagram
|
|
2
|
+
autonumber
|
|
3
|
+
|
|
4
|
+
participant R as Protected Route
|
|
5
|
+
participant VS as validateSession
|
|
6
|
+
participant VT as validateTokenAuthentication
|
|
7
|
+
participant CS as validateCookieSession
|
|
8
|
+
participant DB as DB
|
|
9
|
+
participant RES as Response
|
|
10
|
+
|
|
11
|
+
R->>VS: validateSession(req)
|
|
12
|
+
|
|
13
|
+
alt Authorization header exists
|
|
14
|
+
alt strictTokenValidation is true
|
|
15
|
+
VS-->>RES: 401 INVALID_AUTH_TOKEN
|
|
16
|
+
else token auth allowed
|
|
17
|
+
VS->>VT: validateTokenAuthentication(req)
|
|
18
|
+
|
|
19
|
+
alt Invalid format or missing Bearer
|
|
20
|
+
VT-->>VS: null / error
|
|
21
|
+
VS-->>RES: 401 INVALID_AUTH_TOKEN
|
|
22
|
+
else Token accepted
|
|
23
|
+
VT->>DB: getApiTokenByHash(hash)
|
|
24
|
+
|
|
25
|
+
alt Token not found
|
|
26
|
+
DB-->>VT: null
|
|
27
|
+
VT-->>VS: error
|
|
28
|
+
VS-->>RES: 401 INVALID_AUTH_TOKEN
|
|
29
|
+
else Token expired
|
|
30
|
+
DB-->>VT: expired row
|
|
31
|
+
VT-->>VS: TOKEN_EXPIRED
|
|
32
|
+
VS-->>RES: 401 API_TOKEN_EXPIRED
|
|
33
|
+
else Token found
|
|
34
|
+
DB-->>VT: token row + user
|
|
35
|
+
VT-->>VS: tokenUser
|
|
36
|
+
|
|
37
|
+
alt Account inactive or app not authorized
|
|
38
|
+
VS-->>RES: 401 ACCOUNT_INACTIVE / APP_NOT_AUTHORIZED
|
|
39
|
+
else Access allowed
|
|
40
|
+
VS->>VS: attachApiTokenUser(req)
|
|
41
|
+
|
|
42
|
+
alt Scope disallows method
|
|
43
|
+
VS-->>RES: 403 TOKEN_SCOPE_INSUFFICIENT
|
|
44
|
+
else Scope ok
|
|
45
|
+
VS-->>R: next()
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
else No Authorization header
|
|
52
|
+
VS->>CS: validateCookieSession(req, prefersJson)
|
|
53
|
+
|
|
54
|
+
alt Session missing
|
|
55
|
+
CS-->>RES: 401 SESSION_NOT_FOUND / redirect
|
|
56
|
+
else Session exists
|
|
57
|
+
alt Invalid or missing sessionId UUID
|
|
58
|
+
CS->>CS: destroy session
|
|
59
|
+
CS-->>RES: 401 SESSION_EXPIRED / error page
|
|
60
|
+
else Valid UUID
|
|
61
|
+
CS->>DB: getSessionAuthData(sessionId)
|
|
62
|
+
|
|
63
|
+
alt Row not found
|
|
64
|
+
CS->>CS: destroy session
|
|
65
|
+
CS-->>RES: 401 SESSION_INVALID / error page
|
|
66
|
+
else Row found
|
|
67
|
+
alt Expired, inactive, or app not allowed
|
|
68
|
+
CS->>CS: destroy session
|
|
69
|
+
CS-->>RES: 401 / error page
|
|
70
|
+
else Valid
|
|
71
|
+
CS-->>R: next()
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
opt Unhandled throw
|
|
79
|
+
VS-->>RES: 500 INTERNAL_SERVER_ERROR
|
|
80
|
+
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Environment Configuration Guide
|
|
2
2
|
|
|
3
|
-
[
|
|
3
|
+
[Back to docs index](../README.md) | [Back to project README](../../README.md)
|
|
4
|
+
|
|
4
5
|
This document describes the environment variables MBKAuth expects and keeps brief usage notes for each parameter. Validation and defaults are implemented in `lib/config/index.js` (it parses `mbkautheVar`, applies optional `mbkauthShared` fallbacks, normalizes values, and throws on validation failures).
|
|
5
6
|
|
|
6
7
|
## How configuration is provided
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Database Schema
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[Back to docs index](../README.md) | [Back to project README](../../README.md)
|
|
4
|
+
|
|
5
|
+
**Executable DDL lives only in [`docs/schema/db.sql`](../schema/db.sql).** This file explains what that script creates and how the app uses it. Run the script against Postgres when bootstrapping or aligning a database (for example `psql $DATABASE_URL -f docs/schema/db.sql`). The app can also apply it via `lib/createTable.js`, which reads `docs/schema/db.sql`.
|
|
4
6
|
|
|
5
7
|
---
|
|
6
8
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg id="my-svg" width="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="max-width: 1448.5px; background-color: white;" viewBox="-50 -10 1448.5 2667" role="graphics-document document" aria-roledescription="sequence"><g><rect x="1198.5" y="2581" fill="#eaeaea" stroke="#666" width="150" height="65" name="RES" rx="3" ry="3" class="actor actor-bottom"/><text x="1273.5" y="2613.5" dominant-baseline="central" alignment-baseline="central" class="actor actor-box" style="text-anchor: middle; font-size: 16px; font-weight: 400;"><tspan x="1273.5" dy="0">Response</tspan></text></g><g><rect x="998.5" y="2581" fill="#eaeaea" stroke="#666" width="150" height="65" name="DB" rx="3" ry="3" class="actor actor-bottom"/><text x="1073.5" y="2613.5" dominant-baseline="central" alignment-baseline="central" class="actor actor-box" style="text-anchor: middle; font-size: 16px; font-weight: 400;"><tspan x="1073.5" dy="0">DB</tspan></text></g><g><rect x="718.5" y="2581" fill="#eaeaea" stroke="#666" width="168" height="65" name="CS" rx="3" ry="3" class="actor actor-bottom"/><text x="802.5" y="2613.5" dominant-baseline="central" alignment-baseline="central" class="actor actor-box" style="text-anchor: middle; font-size: 16px; font-weight: 400;"><tspan x="802.5" dy="0">validateCookieSession</tspan></text></g><g><rect x="461.5" y="2581" fill="#eaeaea" stroke="#666" width="207" height="65" name="VT" rx="3" ry="3" class="actor actor-bottom"/><text x="565" y="2613.5" dominant-baseline="central" alignment-baseline="central" class="actor actor-box" style="text-anchor: middle; font-size: 16px; font-weight: 400;"><tspan x="565" dy="0">validateTokenAuthentication</tspan></text></g><g><rect x="202" y="2581" fill="#eaeaea" stroke="#666" width="150" height="65" name="VS" rx="3" ry="3" class="actor actor-bottom"/><text x="277" y="2613.5" dominant-baseline="central" alignment-baseline="central" class="actor actor-box" style="text-anchor: middle; font-size: 16px; font-weight: 400;"><tspan x="277" dy="0">validateSession</tspan></text></g><g><rect x="0" y="2581" fill="#eaeaea" stroke="#666" width="150" height="65" name="R" rx="3" ry="3" class="actor actor-bottom"/><text x="75" y="2613.5" dominant-baseline="central" alignment-baseline="central" class="actor actor-box" style="text-anchor: middle; font-size: 16px; font-weight: 400;"><tspan x="75" dy="0">Protected Route</tspan></text></g><g><line id="actor5" x1="1273.5" y1="65" x2="1273.5" y2="2581" class="actor-line 200" stroke-width="0.5px" stroke="#999" name="RES" data-et="life-line" data-id="RES"/><g id="root-5" data-et="participant" data-type="participant" data-id="RES"><rect x="1198.5" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" name="RES" rx="3" ry="3" class="actor actor-top"/><text x="1273.5" y="32.5" dominant-baseline="central" alignment-baseline="central" class="actor actor-box" style="text-anchor: middle; font-size: 16px; font-weight: 400;"><tspan x="1273.5" dy="0">Response</tspan></text></g></g><g><line id="actor4" x1="1073.5" y1="65" x2="1073.5" y2="2581" class="actor-line 200" stroke-width="0.5px" stroke="#999" name="DB" data-et="life-line" data-id="DB"/><g id="root-4" data-et="participant" data-type="participant" data-id="DB"><rect x="998.5" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" name="DB" rx="3" ry="3" class="actor actor-top"/><text x="1073.5" y="32.5" dominant-baseline="central" alignment-baseline="central" class="actor actor-box" style="text-anchor: middle; font-size: 16px; font-weight: 400;"><tspan x="1073.5" dy="0">DB</tspan></text></g></g><g><line id="actor3" x1="802.5" y1="65" x2="802.5" y2="2581" class="actor-line 200" stroke-width="0.5px" stroke="#999" name="CS" data-et="life-line" data-id="CS"/><g id="root-3" data-et="participant" data-type="participant" data-id="CS"><rect x="718.5" y="0" fill="#eaeaea" stroke="#666" width="168" height="65" name="CS" rx="3" ry="3" class="actor actor-top"/><text x="802.5" y="32.5" dominant-baseline="central" alignment-baseline="central" class="actor actor-box" style="text-anchor: middle; font-size: 16px; font-weight: 400;"><tspan x="802.5" dy="0">validateCookieSession</tspan></text></g></g><g><line id="actor2" x1="565" y1="65" x2="565" y2="2581" class="actor-line 200" stroke-width="0.5px" stroke="#999" name="VT" data-et="life-line" data-id="VT"/><g id="root-2" data-et="participant" data-type="participant" data-id="VT"><rect x="461.5" y="0" fill="#eaeaea" stroke="#666" width="207" height="65" name="VT" rx="3" ry="3" class="actor actor-top"/><text x="565" y="32.5" dominant-baseline="central" alignment-baseline="central" class="actor actor-box" style="text-anchor: middle; font-size: 16px; font-weight: 400;"><tspan x="565" dy="0">validateTokenAuthentication</tspan></text></g></g><g><line id="actor1" x1="277" y1="65" x2="277" y2="2581" class="actor-line 200" stroke-width="0.5px" stroke="#999" name="VS" data-et="life-line" data-id="VS"/><g id="root-1" data-et="participant" data-type="participant" data-id="VS"><rect x="202" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" name="VS" rx="3" ry="3" class="actor actor-top"/><text x="277" y="32.5" dominant-baseline="central" alignment-baseline="central" class="actor actor-box" style="text-anchor: middle; font-size: 16px; font-weight: 400;"><tspan x="277" dy="0">validateSession</tspan></text></g></g><g><line id="actor0" x1="75" y1="65" x2="75" y2="2581" class="actor-line 200" stroke-width="0.5px" stroke="#999" name="R" data-et="life-line" data-id="R"/><g id="root-0" data-et="participant" data-type="participant" data-id="R"><rect x="0" y="0" fill="#eaeaea" stroke="#666" width="150" height="65" name="R" rx="3" ry="3" class="actor actor-top"/><text x="75" y="32.5" dominant-baseline="central" alignment-baseline="central" class="actor actor-box" style="text-anchor: middle; font-size: 16px; font-weight: 400;"><tspan x="75" dy="0">Protected Route</tspan></text></g></g><style>#my-svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#my-svg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#my-svg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#my-svg .error-icon{fill:#552222;}#my-svg .error-text{fill:#552222;stroke:#552222;}#my-svg .edge-thickness-normal{stroke-width:1px;}#my-svg .edge-thickness-thick{stroke-width:3.5px;}#my-svg .edge-pattern-solid{stroke-dasharray:0;}#my-svg .edge-thickness-invisible{stroke-width:0;fill:none;}#my-svg .edge-pattern-dashed{stroke-dasharray:3;}#my-svg .edge-pattern-dotted{stroke-dasharray:2;}#my-svg .marker{fill:#333333;stroke:#333333;}#my-svg .marker.cross{stroke:#333333;}#my-svg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#my-svg p{margin:0;}#my-svg .actor{stroke:#9370DB;fill:#ECECFF;stroke-width:1;}#my-svg rect.actor.outer-path[data-look="neo"]{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg rect.note[data-look="neo"]{stroke:#aaaa33;fill:#fff5ad;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg text.actor>tspan{fill:black;stroke:none;}#my-svg .actor-line{stroke:#9370DB;}#my-svg .innerArc{stroke-width:1.5;stroke-dasharray:none;}#my-svg .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#my-svg .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#my-svg [id$="-arrowhead"] path{fill:#333;stroke:#333;}#my-svg .sequenceNumber{fill:white;}#my-svg [id$="-sequencenumber"]{fill:#333;}#my-svg [id$="-crosshead"] path{fill:#333;stroke:#333;}#my-svg .messageText{fill:#333;stroke:none;}#my-svg .labelBox{stroke:#9370DB;fill:#ECECFF;filter:none;}#my-svg .labelText,#my-svg .labelText>tspan{fill:black;stroke:none;}#my-svg .loopText,#my-svg .loopText>tspan{fill:black;stroke:none;}#my-svg .sectionTitle,#my-svg .sectionTitle>tspan{fill:black;stroke:none;}#my-svg .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:#9370DB;fill:#9370DB;}#my-svg .note{stroke:#aaaa33;fill:#fff5ad;}#my-svg .noteText,#my-svg .noteText>tspan{fill:black;stroke:none;font-weight:normal;}#my-svg .activation0{fill:#f4f4f4;stroke:#666;}#my-svg .activation1{fill:#f4f4f4;stroke:#666;}#my-svg .activation2{fill:#f4f4f4;stroke:#666;}#my-svg .actorPopupMenu{position:absolute;}#my-svg .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#my-svg .actor-man circle,#my-svg line{fill:#ECECFF;stroke-width:2px;}#my-svg g rect.rect{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));stroke:#9370DB;}#my-svg .node .neo-node{stroke:#9370DB;}#my-svg [data-look="neo"].node rect,#my-svg [data-look="neo"].cluster rect,#my-svg [data-look="neo"].node polygon{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg [data-look="neo"].node path{stroke:#9370DB;stroke-width:1px;}#my-svg [data-look="neo"].node .outer-path{filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg [data-look="neo"].node .neo-line path{stroke:#9370DB;filter:none;}#my-svg [data-look="neo"].node circle{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg [data-look="neo"].node circle .state-start{fill:#000000;}#my-svg [data-look="neo"].icon-shape .icon{fill:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg [data-look="neo"].icon-shape .icon-neo path{stroke:#9370DB;filter:drop-shadow(1px 2px 2px rgba(185, 185, 185, 1));}#my-svg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}</style><g/><defs><symbol id="my-svg-computer" width="24" height="24"><path transform="scale(.5)" d="M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z"/></symbol></defs><defs><symbol id="my-svg-database" fill-rule="evenodd" clip-rule="evenodd"><path transform="scale(.5)" d="M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z"/></symbol></defs><defs><symbol id="my-svg-clock" width="24" height="24"><path transform="scale(.5)" d="M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z"/></symbol></defs><defs><marker id="my-svg-arrowhead" refX="7.9" refY="5" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto-start-reverse"><path d="M -1 0 L 10 5 L 0 10 z"/></marker></defs><defs><marker id="my-svg-crosshead" markerWidth="15" markerHeight="8" orient="auto" refX="4" refY="4.5"><path fill="none" stroke="#000000" stroke-width="1pt" d="M 1,2 L 6,7 M 6,2 L 1,7" style="stroke-dasharray: 0, 0;"/></marker></defs><defs><marker id="my-svg-filled-head" refX="15.5" refY="7" markerWidth="20" markerHeight="28" orient="auto"><path d="M 18,7 L9,13 L14,7 L9,1 Z"/></marker></defs><defs><marker id="my-svg-sequencenumber" refX="15" refY="15" markerWidth="60" markerHeight="40" orient="auto"><circle cx="15" cy="15" r="6"/></marker></defs><defs><marker id="my-svg-solidTopArrowHead" refX="7.9" refY="7.25" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto-start-reverse"><path d="M 0 0 L 10 8 L 0 8 z"/></marker></defs><defs><marker id="my-svg-solidBottomArrowHead" refX="7.9" refY="0.75" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto-start-reverse"><path d="M 0 0 L 10 0 L 0 8 z"/></marker></defs><defs><marker id="my-svg-stickTopArrowHead" refX="7.5" refY="7" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto-start-reverse"><path d="M 0 0 L 7 7" stroke="black" stroke-width="1.5" fill="none"/></marker></defs><defs><marker id="my-svg-stickBottomArrowHead" refX="7.5" refY="0" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12" orient="auto-start-reverse"><path d="M 0 7 L 7 0" stroke="black" stroke-width="1.5" fill="none"/></marker></defs><g data-et="control-structure" data-id="i31"><line x1="64" y1="1259" x2="1284.5" y2="1259" class="loopLine"/><line x1="1284.5" y1="1259" x2="1284.5" y2="1437" class="loopLine"/><line x1="64" y1="1437" x2="1284.5" y2="1437" class="loopLine"/><line x1="64" y1="1259" x2="64" y2="1437" class="loopLine"/><line x1="64" y1="1353" x2="1284.5" y2="1353" class="loopLine" style="stroke-dasharray: 3, 3;"/><polygon points="64,1259 114,1259 114,1272 105.6,1279 64,1279" class="labelBox"/><text x="89" y="1272" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="labelText" style="font-size: 16px; font-weight: 400;">alt</text><text x="699.25" y="1277" text-anchor="middle" class="loopText" style="font-size: 16px; font-weight: 400;"><tspan x="699.25">[Scope disallows method]</tspan></text><text x="674.25" y="1371" text-anchor="middle" class="sectionTitle" style="font-size: 16px; font-weight: 400;">[Scope ok]</text></g><g data-et="control-structure" data-id="i32"><line x1="54" y1="1051" x2="1294.5" y2="1051" class="loopLine"/><line x1="1294.5" y1="1051" x2="1294.5" y2="1447" class="loopLine"/><line x1="54" y1="1447" x2="1294.5" y2="1447" class="loopLine"/><line x1="54" y1="1051" x2="54" y2="1447" class="loopLine"/><line x1="54" y1="1145" x2="1294.5" y2="1145" class="loopLine" style="stroke-dasharray: 3, 3;"/><polygon points="54,1051 104,1051 104,1064 95.6,1071 54,1071" class="labelBox"/><text x="79" y="1064" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="labelText" style="font-size: 16px; font-weight: 400;">alt</text><text x="699.25" y="1069" text-anchor="middle" class="loopText" style="font-size: 16px; font-weight: 400;"><tspan x="699.25">[Account inactive or app not authorized]</tspan></text><text x="674.25" y="1163" text-anchor="middle" class="sectionTitle" style="font-size: 16px; font-weight: 400;">[Access allowed]</text></g><g data-et="control-structure" data-id="i33"><line x1="44" y1="564" x2="1304.5" y2="564" class="loopLine"/><line x1="1304.5" y1="564" x2="1304.5" y2="1457" class="loopLine"/><line x1="44" y1="1457" x2="1304.5" y2="1457" class="loopLine"/><line x1="44" y1="564" x2="44" y2="1457" class="loopLine"/><line x1="44" y1="746" x2="1304.5" y2="746" class="loopLine" style="stroke-dasharray: 3, 3;"/><line x1="44" y1="923" x2="1304.5" y2="923" class="loopLine" style="stroke-dasharray: 3, 3;"/><polygon points="44,564 94,564 94,577 85.6,584 44,584" class="labelBox"/><text x="69" y="577" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="labelText" style="font-size: 16px; font-weight: 400;">alt</text><text x="699.25" y="582" text-anchor="middle" class="loopText" style="font-size: 16px; font-weight: 400;"><tspan x="699.25">[Token not found]</tspan></text><text x="674.25" y="764" text-anchor="middle" class="sectionTitle" style="font-size: 16px; font-weight: 400;">[Token expired]</text><text x="674.25" y="941" text-anchor="middle" class="sectionTitle" style="font-size: 16px; font-weight: 400;">[Token found]</text></g><g data-et="control-structure" data-id="i34"><line x1="34" y1="342" x2="1314.5" y2="342" class="loopLine"/><line x1="1314.5" y1="342" x2="1314.5" y2="1467" class="loopLine"/><line x1="34" y1="1467" x2="1314.5" y2="1467" class="loopLine"/><line x1="34" y1="342" x2="34" y2="1467" class="loopLine"/><line x1="34" y1="480" x2="1314.5" y2="480" class="loopLine" style="stroke-dasharray: 3, 3;"/><polygon points="34,342 84,342 84,355 75.6,362 34,362" class="labelBox"/><text x="59" y="355" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="labelText" style="font-size: 16px; font-weight: 400;">alt</text><text x="699.25" y="360" text-anchor="middle" class="loopText" style="font-size: 16px; font-weight: 400;"><tspan x="699.25">[Invalid format or missing Bearer]</tspan></text><text x="674.25" y="498" text-anchor="middle" class="sectionTitle" style="font-size: 16px; font-weight: 400;">[Token accepted]</text></g><g data-et="control-structure" data-id="i35"><line x1="24" y1="164" x2="1324.5" y2="164" class="loopLine"/><line x1="1324.5" y1="164" x2="1324.5" y2="1477" class="loopLine"/><line x1="24" y1="1477" x2="1324.5" y2="1477" class="loopLine"/><line x1="24" y1="164" x2="24" y2="1477" class="loopLine"/><line x1="24" y1="258" x2="1324.5" y2="258" class="loopLine" style="stroke-dasharray: 3, 3;"/><polygon points="24,164 74,164 74,177 65.6,184 24,184" class="labelBox"/><text x="49" y="177" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="labelText" style="font-size: 16px; font-weight: 400;">alt</text><text x="699.25" y="182" text-anchor="middle" class="loopText" style="font-size: 16px; font-weight: 400;"><tspan x="699.25">[strictTokenValidation is true]</tspan></text><text x="674.25" y="276" text-anchor="middle" class="sectionTitle" style="font-size: 16px; font-weight: 400;">[token auth allowed]</text></g><g data-et="control-structure" data-id="i55"><line x1="64" y1="2170" x2="1284.5" y2="2170" class="loopLine"/><line x1="1284.5" y1="2170" x2="1284.5" y2="2422" class="loopLine"/><line x1="64" y1="2422" x2="1284.5" y2="2422" class="loopLine"/><line x1="64" y1="2170" x2="64" y2="2422" class="loopLine"/><line x1="64" y1="2338" x2="1284.5" y2="2338" class="loopLine" style="stroke-dasharray: 3, 3;"/><polygon points="64,2170 114,2170 114,2183 105.6,2190 64,2190" class="labelBox"/><text x="89" y="2183" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="labelText" style="font-size: 16px; font-weight: 400;">alt</text><text x="699.25" y="2188" text-anchor="middle" class="loopText" style="font-size: 16px; font-weight: 400;"><tspan x="699.25">[Expired, inactive, or app not allowed]</tspan></text><text x="674.25" y="2356" text-anchor="middle" class="sectionTitle" style="font-size: 16px; font-weight: 400;">[Valid]</text></g><g data-et="control-structure" data-id="i56"><line x1="54" y1="1962" x2="1294.5" y2="1962" class="loopLine"/><line x1="1294.5" y1="1962" x2="1294.5" y2="2432" class="loopLine"/><line x1="54" y1="2432" x2="1294.5" y2="2432" class="loopLine"/><line x1="54" y1="1962" x2="54" y2="2432" class="loopLine"/><line x1="54" y1="2130" x2="1294.5" y2="2130" class="loopLine" style="stroke-dasharray: 3, 3;"/><polygon points="54,1962 104,1962 104,1975 95.6,1982 54,1982" class="labelBox"/><text x="79" y="1975" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="labelText" style="font-size: 16px; font-weight: 400;">alt</text><text x="699.25" y="1980" text-anchor="middle" class="loopText" style="font-size: 16px; font-weight: 400;"><tspan x="699.25">[Row not found]</tspan></text><text x="674.25" y="2148" text-anchor="middle" class="sectionTitle" style="font-size: 16px; font-weight: 400;">[Row found]</text></g><g data-et="control-structure" data-id="i57"><line x1="44" y1="1710" x2="1304.5" y2="1710" class="loopLine"/><line x1="1304.5" y1="1710" x2="1304.5" y2="2442" class="loopLine"/><line x1="44" y1="2442" x2="1304.5" y2="2442" class="loopLine"/><line x1="44" y1="1710" x2="44" y2="2442" class="loopLine"/><line x1="44" y1="1878" x2="1304.5" y2="1878" class="loopLine" style="stroke-dasharray: 3, 3;"/><polygon points="44,1710 94,1710 94,1723 85.6,1730 44,1730" class="labelBox"/><text x="69" y="1723" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="labelText" style="font-size: 16px; font-weight: 400;">alt</text><text x="699.25" y="1728" text-anchor="middle" class="loopText" style="font-size: 16px; font-weight: 400;"><tspan x="699.25">[Invalid or missing sessionId UUID]</tspan></text><text x="674.25" y="1896" text-anchor="middle" class="sectionTitle" style="font-size: 16px; font-weight: 400;">[Valid UUID]</text></g><g data-et="control-structure" data-id="i58"><line x1="34" y1="1576" x2="1314.5" y2="1576" class="loopLine"/><line x1="1314.5" y1="1576" x2="1314.5" y2="2452" class="loopLine"/><line x1="34" y1="2452" x2="1314.5" y2="2452" class="loopLine"/><line x1="34" y1="1576" x2="34" y2="2452" class="loopLine"/><line x1="34" y1="1670" x2="1314.5" y2="1670" class="loopLine" style="stroke-dasharray: 3, 3;"/><polygon points="34,1576 84,1576 84,1589 75.6,1596 34,1596" class="labelBox"/><text x="59" y="1589" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="labelText" style="font-size: 16px; font-weight: 400;">alt</text><text x="699.25" y="1594" text-anchor="middle" class="loopText" style="font-size: 16px; font-weight: 400;"><tspan x="699.25">[Session missing]</tspan></text><text x="674.25" y="1688" text-anchor="middle" class="sectionTitle" style="font-size: 16px; font-weight: 400;">[Session exists]</text></g><g data-et="control-structure" data-id="i59"><line x1="14" y1="119" x2="1334.5" y2="119" class="loopLine"/><line x1="1334.5" y1="119" x2="1334.5" y2="2462" class="loopLine"/><line x1="14" y1="2462" x2="1334.5" y2="2462" class="loopLine"/><line x1="14" y1="119" x2="14" y2="2462" class="loopLine"/><line x1="14" y1="1492" x2="1334.5" y2="1492" class="loopLine" style="stroke-dasharray: 3, 3;"/><polygon points="14,119 64,119 64,132 55.6,139 14,139" class="labelBox"/><text x="39" y="132" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="labelText" style="font-size: 16px; font-weight: 400;">alt</text><text x="699.25" y="137" text-anchor="middle" class="loopText" style="font-size: 16px; font-weight: 400;"><tspan x="699.25">[Authorization header exists]</tspan></text><text x="674.25" y="1510" text-anchor="middle" class="sectionTitle" style="font-size: 16px; font-weight: 400;">[No Authorization header]</text></g><g data-et="control-structure" data-id="i62"><line x1="266" y1="2472" x2="1284.5" y2="2472" class="loopLine"/><line x1="1284.5" y1="2472" x2="1284.5" y2="2561" class="loopLine"/><line x1="266" y1="2561" x2="1284.5" y2="2561" class="loopLine"/><line x1="266" y1="2472" x2="266" y2="2561" class="loopLine"/><polygon points="266,2472 316,2472 316,2485 307.6,2492 266,2492" class="labelBox"/><text x="291" y="2485" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="labelText" style="font-size: 16px; font-weight: 400;">opt</text><text x="800.25" y="2490" text-anchor="middle" class="loopText" style="font-size: 16px; font-weight: 400;"><tspan x="800.25">[Unhandled throw]</tspan></text></g><text x="175" y="80" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">validateSession(req)</text><line x1="82" y1="109" x2="273" y2="109" class="messageLine0" data-et="message" data-id="i1" data-from="R" data-to="VS" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><line x1="75" y1="109" x2="75" y2="109" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="75" y="113" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">1</text><text x="774" y="214" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">401 INVALID_AUTH_TOKEN</text><line x1="284" y1="243" x2="1269.5" y2="243" class="messageLine1" data-et="message" data-id="i4" data-from="VS" data-to="RES" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><line x1="277" y1="243" x2="277" y2="243" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="277" y="247" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">2</text><text x="420" y="303" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">validateTokenAuthentication(req)</text><line x1="284" y1="332" x2="561" y2="332" class="messageLine0" data-et="message" data-id="i6" data-from="VS" data-to="VT" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><line x1="277" y1="332" x2="277" y2="332" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="277" y="336" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">3</text><text x="423" y="392" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">null / error</text><line x1="570" y1="421" x2="281" y2="421" class="messageLine1" data-et="message" data-id="i8" data-from="VT" data-to="VS" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><line x1="565" y1="421" x2="565" y2="421" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="565" y="425" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">4</text><text x="774" y="436" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">401 INVALID_AUTH_TOKEN</text><line x1="284" y1="465" x2="1269.5" y2="465" class="messageLine1" data-et="message" data-id="i9" data-from="VS" data-to="RES" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><line x1="277" y1="465" x2="277" y2="465" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="277" y="469" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">5</text><text x="818" y="525" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">getApiTokenByHash(hash)</text><line x1="572" y1="554" x2="1069.5" y2="554" class="messageLine0" data-et="message" data-id="i11" data-from="VT" data-to="DB" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><line x1="565" y1="554" x2="565" y2="554" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="565" y="558" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">6</text><text x="821" y="614" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">null</text><line x1="1078.5" y1="643" x2="569" y2="643" class="messageLine1" data-et="message" data-id="i13" data-from="DB" data-to="VT" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><line x1="1073.5" y1="643" x2="1073.5" y2="643" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="1073.5" y="647" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">7</text><text x="423" y="658" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">error</text><line x1="570" y1="687" x2="281" y2="687" class="messageLine1" data-et="message" data-id="i14" data-from="VT" data-to="VS" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><line x1="565" y1="687" x2="565" y2="687" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="565" y="691" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">8</text><text x="774" y="702" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">401 INVALID_AUTH_TOKEN</text><line x1="284" y1="731" x2="1269.5" y2="731" class="messageLine1" data-et="message" data-id="i15" data-from="VS" data-to="RES" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><line x1="277" y1="731" x2="277" y2="731" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="277" y="735" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">9</text><text x="821" y="791" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">expired row</text><line x1="1078.5" y1="820" x2="569" y2="820" class="messageLine1" data-et="message" data-id="i17" data-from="DB" data-to="VT" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><line x1="1073.5" y1="820" x2="1073.5" y2="820" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="1073.5" y="824" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">10</text><text x="423" y="835" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">TOKEN_EXPIRED</text><line x1="570" y1="864" x2="281" y2="864" class="messageLine1" data-et="message" data-id="i18" data-from="VT" data-to="VS" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><line x1="565" y1="864" x2="565" y2="864" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="565" y="868" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">11</text><text x="774" y="879" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">401 API_TOKEN_EXPIRED</text><line x1="284" y1="908" x2="1269.5" y2="908" class="messageLine1" data-et="message" data-id="i19" data-from="VS" data-to="RES" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><line x1="277" y1="908" x2="277" y2="908" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="277" y="912" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">12</text><text x="821" y="968" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">token row + user</text><line x1="1078.5" y1="997" x2="569" y2="997" class="messageLine1" data-et="message" data-id="i21" data-from="DB" data-to="VT" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><line x1="1073.5" y1="997" x2="1073.5" y2="997" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="1073.5" y="1001" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">13</text><text x="423" y="1012" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">tokenUser</text><line x1="570" y1="1041" x2="281" y2="1041" class="messageLine1" data-et="message" data-id="i22" data-from="VT" data-to="VS" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><line x1="565" y1="1041" x2="565" y2="1041" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="565" y="1045" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">14</text><text x="774" y="1101" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">401 ACCOUNT_INACTIVE / APP_NOT_AUTHORIZED</text><line x1="284" y1="1130" x2="1269.5" y2="1130" class="messageLine1" data-et="message" data-id="i24" data-from="VS" data-to="RES" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><line x1="277" y1="1130" x2="277" y2="1130" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="277" y="1134" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">15</text><text x="278" y="1190" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">attachApiTokenUser(req)</text><path d="M 278,1219 C 338,1209 338,1249 278,1239" class="messageLine0" data-et="message" data-id="i26" data-from="VS" data-to="VS" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" x1="284" style="fill: none;"/><line x1="277" y1="1219" x2="277" y2="1219" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="277" y="1223" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">16</text><text x="774" y="1309" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">403 TOKEN_SCOPE_INSUFFICIENT</text><line x1="284" y1="1338" x2="1269.5" y2="1338" class="messageLine1" data-et="message" data-id="i28" data-from="VS" data-to="RES" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><line x1="277" y1="1338" x2="277" y2="1338" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="277" y="1342" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">17</text><text x="178" y="1398" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">next()</text><line x1="282" y1="1427" x2="79" y2="1427" class="messageLine1" data-et="message" data-id="i30" data-from="VS" data-to="R" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><line x1="277" y1="1427" x2="277" y2="1427" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="277" y="1431" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">18</text><text x="538" y="1537" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">validateCookieSession(req, prefersJson)</text><line x1="284" y1="1566" x2="798.5" y2="1566" class="messageLine0" data-et="message" data-id="i37" data-from="VS" data-to="CS" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><line x1="277" y1="1566" x2="277" y2="1566" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="277" y="1570" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">19</text><text x="1037" y="1626" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">401 SESSION_NOT_FOUND / redirect</text><line x1="809.5" y1="1655" x2="1269.5" y2="1655" class="messageLine1" data-et="message" data-id="i39" data-from="CS" data-to="RES" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><line x1="802.5" y1="1655" x2="802.5" y2="1655" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="802.5" y="1659" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">20</text><text x="804" y="1760" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">destroy session</text><path d="M 803.5,1789 C 863.5,1779 863.5,1819 803.5,1809" class="messageLine0" data-et="message" data-id="i42" data-from="CS" data-to="CS" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" x1="809.5" style="fill: none;"/><line x1="802.5" y1="1789" x2="802.5" y2="1789" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="802.5" y="1793" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">21</text><text x="1037" y="1834" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">401 SESSION_EXPIRED / error page</text><line x1="809.5" y1="1863" x2="1269.5" y2="1863" class="messageLine1" data-et="message" data-id="i43" data-from="CS" data-to="RES" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><line x1="802.5" y1="1863" x2="802.5" y2="1863" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="802.5" y="1867" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">22</text><text x="937" y="1923" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">getSessionAuthData(sessionId)</text><line x1="809.5" y1="1952" x2="1069.5" y2="1952" class="messageLine0" data-et="message" data-id="i45" data-from="CS" data-to="DB" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="fill: none;"/><line x1="802.5" y1="1952" x2="802.5" y2="1952" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="802.5" y="1956" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">23</text><text x="804" y="2012" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">destroy session</text><path d="M 803.5,2041 C 863.5,2031 863.5,2071 803.5,2061" class="messageLine0" data-et="message" data-id="i47" data-from="CS" data-to="CS" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" x1="809.5" style="fill: none;"/><line x1="802.5" y1="2041" x2="802.5" y2="2041" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="802.5" y="2045" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">24</text><text x="1037" y="2086" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">401 SESSION_INVALID / error page</text><line x1="809.5" y1="2115" x2="1269.5" y2="2115" class="messageLine1" data-et="message" data-id="i48" data-from="CS" data-to="RES" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><line x1="802.5" y1="2115" x2="802.5" y2="2115" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="802.5" y="2119" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">25</text><text x="804" y="2220" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">destroy session</text><path d="M 803.5,2249 C 863.5,2239 863.5,2279 803.5,2269" class="messageLine0" data-et="message" data-id="i51" data-from="CS" data-to="CS" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" x1="809.5" style="fill: none;"/><line x1="802.5" y1="2249" x2="802.5" y2="2249" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="802.5" y="2253" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">26</text><text x="1037" y="2294" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">401 / error page</text><line x1="809.5" y1="2323" x2="1269.5" y2="2323" class="messageLine1" data-et="message" data-id="i52" data-from="CS" data-to="RES" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><line x1="802.5" y1="2323" x2="802.5" y2="2323" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="802.5" y="2327" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">27</text><text x="440" y="2383" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">next()</text><line x1="807.5" y1="2412" x2="79" y2="2412" class="messageLine1" data-et="message" data-id="i54" data-from="CS" data-to="R" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><line x1="802.5" y1="2412" x2="802.5" y2="2412" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="802.5" y="2416" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">28</text><text x="774" y="2522" text-anchor="middle" dominant-baseline="middle" alignment-baseline="middle" class="messageText" dy="1em" style="font-size: 16px; font-weight: 400;">500 INTERNAL_SERVER_ERROR</text><line x1="284" y1="2551" x2="1269.5" y2="2551" class="messageLine1" data-et="message" data-id="i61" data-from="VS" data-to="RES" stroke-width="2" stroke="none" marker-end="url(#my-svg-arrowhead)" style="stroke-dasharray: 3, 3; fill: none;"/><line x1="277" y1="2551" x2="277" y2="2551" stroke-width="0" marker-start="url(#my-svg-sequencenumber)"/><text x="277" y="2555" font-family="sans-serif" font-size="12px" text-anchor="middle" class="sequenceNumber">29</text></svg>
|