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/README.md CHANGED
@@ -6,172 +6,158 @@
6
6
  [![Publish](https://github.com/MIbnEKhalid/mbkauthe/actions/workflows/publish.yml/badge.svg?branch=main)](https://github.com/MIbnEKhalid/mbkauthe/actions/workflows/publish.yml)
7
7
  [![Downloads](https://img.shields.io/npm/dm/mbkauthe.svg)](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 package focused on login, authentication, and validating sessions for your desired apps in Node.js with Express and PostgreSQL. It provides secure login, session validation, 2FA, role/app access checks, OAuth (GitHub & Google), multi-session support, and related authentication flows.
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
- ## Todo
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
- ## ✨ Key Features
17
+ ## Features
22
18
 
23
- - Compatible With Serverless Function (Vercel)
24
- - Secure password authentication (PBKDF2)
25
- - PostgreSQL session management
26
- - Multi-session support (configurable concurrent sessions per user)
27
- - Optional TOTP-based 2FA with trusted devices
28
- - Social login (GitHub App & Google OAuth)
29
- - Role-based access: SuperAdmin, NormalUser, Guest, member
30
- - CSRF protection & rate limiting
31
- - Easy Express.js integration
32
- - Customizable Handlebars templates
33
- - Session fixation prevention
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
- ## 📦 Installation
31
+ ## Installation
39
32
 
40
33
  ```bash
41
34
  npm install mbkauthe
42
35
  ```
43
36
 
44
- ## 🚀 Quick Start
37
+ ## Quick Start
45
38
 
46
- **1. Configure Environment**
39
+ 1. Copy the environment template.
47
40
 
48
- ```bash
41
+ ```powershell
49
42
  Copy-Item .env.example .env
50
43
  ```
51
- See [docs/env.md](docs/env.md).
52
44
 
53
- **2. Set Up Database**
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
- **3. Integrate with Express**
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
- const app = express();
65
- app.use(mbkauthe);
49
+ 3. Create database tables.
66
50
 
67
- app.get('/dashboard', sessVal, (req, res) => res.send(`Welcome ${req.session.user.username}!`));
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 test
77
- npm run test:watch
78
- npm run dev
54
+ npm run create-tables
79
55
  ```
80
56
 
81
- ## 🔧 Core API
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
- - **Session Validation:** `validateSession`
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
- ## 🧾 JSON Responses (HTML vs JSON)
89
-
90
- Most browser page routes render HTML on auth errors, while API/AJAX-style requests receive JSON error responses.
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
- **Example (force JSON errors):**
101
- ```bash
102
- curl -i -H "User-Agent: json" http://localhost:3000/mbkauthe/test
103
- ```
66
+ dotenv.config();
104
67
 
105
- ## 🧰 Diagnostics (dev only)
68
+ const app = express();
106
69
 
107
- These are only mounted when `process.env.env === "dev"`:
70
+ app.use(mbkauthe);
108
71
 
109
- - **DB Query Monitor (HTML):** `/mbkauthe/db`
110
- - **DB Query Monitor (JSON):** `/mbkauthe/db.json`
111
- - **SuperAdmin check:** `/mbkauthe/validate-superadmin`
72
+ app.get("/dashboard", sessVal, (req, res) => {
73
+ res.send(`Welcome ${req.session.user.username}!`);
74
+ });
112
75
 
113
- ## 🔐 Security
76
+ app.get("/admin", sessVal, roleChk("SuperAdmin"), (req, res) => {
77
+ res.send("Admin Panel");
78
+ });
114
79
 
115
- - Rate limiting, CSRF protection, secure cookies
116
- - Password hashing (PBKDF2, 100k iterations)
117
- - PostgreSQL-backed sessions with automatic cleanup
118
- - OAuth with state validation and secure callbacks
80
+ app.listen(3000);
81
+ ```
119
82
 
120
- ## 📱 Two-Factor Authentication
83
+ ## Common Exports
121
84
 
122
- Enable via `MBKAUTH_TWO_FA_ENABLE=true`. Trusted devices can skip 2FA for a set duration.
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
- ## 🔄 Social Login Integration
93
+ See the [API reference](docs/reference/api.md) for endpoints, middleware, examples, security notes, and rate limits.
125
94
 
126
- **GitHub App / Google OAuth:** Configure credentials via `.env` or `mbkautheVar`. Users must link accounts before login.
95
+ ## JSON Error Responses
127
96
 
128
- ## 🎨 Customization
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
- - **Redirect URL:** `mbkautheVar={"loginRedirectURL":"/dashboard"}`
131
- - **Custom Views:** `views/loginmbkauthe.handlebars`, `2fa.handlebars`, `Error/dError.handlebars`
132
- - **Database Access:** `import { dblogin } from 'mbkauthe'; const result = await dblogin.query('SELECT * FROM "Users"');`
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
- ## 📄 API Reference
105
+ ```bash
106
+ curl -i -H "User-Agent: json" http://localhost:3000/mbkauthe/test
107
+ ```
135
108
 
136
- - Full endpoint list and details: [docs/api.md](docs/api.md)
109
+ ## Development
137
110
 
138
- ## 🧰 Diagnostics (dev only)
111
+ ```bash
112
+ npm test
113
+ npm run test:watch
114
+ npm run dev
115
+ ```
139
116
 
140
- - **DB Query Monitor (HTML):** `/mbkauthe/db`
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
- These routes are only mounted when `process.env.env === "dev"`. They expose query timing, status/error, pool stats, request context, and callsite data for troubleshooting.
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
- ## 🚢 Deployment
124
+ ## Documentation
147
125
 
148
- Checklist for production:
149
- - `IS_DEPLOYED=true`
150
- - Strong secrets for SESSION_SECRET_KEY & Main_SECRET_TOKEN
151
- - HTTPS enabled
152
- - Correct DOMAIN & COOKIE_EXPIRE_TIME
153
- - Use environment variables for all secrets
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
- **Vercel:** Supports shared OAuth credentials via `mbkauthShared`.
138
+ ## Deployment Checklist
156
139
 
157
- ## 📚 Documentation
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
- - [API Reference](docs/api.md)
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
- ## 📝 License
150
+ ## License
165
151
 
166
- GPL v2.0 see [LICENSE](LICENSE)
152
+ GPL v2.0 - see [LICENSE](LICENSE).
167
153
 
168
- ## 👨‍💻 Author
154
+ ## Author
169
155
 
170
156
  **Muhammad Bin Khalid**
171
- 📧 [support@mbktech.org](mailto:support@mbktech.org) | [chmuhammadbinkhalid28@gmail.com](mailto:chmuhammadbinkhalid28@gmail.com)
172
- 🔗 [GitHub @MIbnEKhalid](https://github.com/MIbnEKhalid)
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
- ## 🔗 Links
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 ❤️ by [MBKTech.org](https://mbktech.org)
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
- [ Back to README](README.md)
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
- **Executable DDL lives only in [`docs/db.sql`](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/db.sql`). The app can also apply it via `lib/createTable.js`, which reads `docs/db.sql`.
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&gt;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&gt;tspan{fill:black;stroke:none;}#my-svg .loopText,#my-svg .loopText&gt;tspan{fill:black;stroke:none;}#my-svg .sectionTitle,#my-svg .sectionTitle&gt;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&gt;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>