@qodalis/cli-server-plugin-admin 1.0.0-beta.12 → 1.0.0-beta.13
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 +51 -2
- package/dashboard/assets/{index-CThBrI8x.js → index-BVWEEAZ_.js} +48 -48
- package/dashboard/assets/{index-SAFC7f6i.css → index-DDYjltKc.css} +1 -1
- package/dashboard/index.html +2 -2
- package/dist/auth/auth-controller.d.ts +7 -2
- package/dist/auth/auth-controller.d.ts.map +1 -1
- package/dist/auth/auth-controller.js +26 -3
- package/dist/auth/auth-controller.js.map +1 -1
- package/dist/auth/auth-middleware.d.ts +1 -1
- package/dist/auth/auth-middleware.d.ts.map +1 -1
- package/dist/auth/auth-middleware.js +31 -2
- package/dist/auth/auth-middleware.js.map +1 -1
- package/dist/auth/auth-provider.d.ts +9 -0
- package/dist/auth/auth-provider.d.ts.map +1 -1
- package/dist/auth/auth-provider.js.map +1 -1
- package/dist/cli-admin-builder.d.ts +7 -0
- package/dist/cli-admin-builder.d.ts.map +1 -1
- package/dist/cli-admin-builder.js +19 -5
- package/dist/cli-admin-builder.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/services/admin-config.d.ts +17 -0
- package/dist/services/admin-config.d.ts.map +1 -1
- package/dist/services/admin-config.js +41 -0
- package/dist/services/admin-config.js.map +1 -1
- package/dist/services/module-registry.d.ts +8 -0
- package/dist/services/module-registry.d.ts.map +1 -1
- package/dist/services/module-registry.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -52,7 +52,8 @@ Credentials and JWT secret can be set via the builder or environment variables:
|
|
|
52
52
|
| `setCredentials(username, password)` | Set admin login credentials (only used without the users plugin) |
|
|
53
53
|
| `setAuthProvider(usersPlugin.serverAuth)` | Log in through the users plugin; requires the `admin:access` permission (`admin` has it via `*`) |
|
|
54
54
|
| `setJwtSecret(secret)` | Set JWT signing secret |
|
|
55
|
-
| `
|
|
55
|
+
| `setSignInUrl(url)` | Where the host app signs users in, for external sign-in mode (see [Sign in with the host app's session](#sign-in-with-the-host-apps-session)); `build()` throws on an invalid URL |
|
|
56
|
+
| `setRegisteredJobs(count)` | Report job count in the status endpoint (`jobs` is listed in `enabledFeatures` once the jobs plugin is mounted, or with a count above 0) |
|
|
56
57
|
| `setEnabledFeatures(features)` | Add custom feature flags to the status endpoint |
|
|
57
58
|
| `setDashboardDir(dir)` | Override the path to the dashboard SPA dist directory |
|
|
58
59
|
| `setTheme(theme)` | Dashboard color scheme: mode and per-scheme colors (see [Color scheme](#color-scheme)) |
|
|
@@ -65,7 +66,8 @@ All endpoints are mounted at the plugin's built-in prefix (`/api/v1/qcli`). Rout
|
|
|
65
66
|
|
|
66
67
|
| Method | Endpoint | Description |
|
|
67
68
|
|---|---|---|
|
|
68
|
-
|
|
|
69
|
+
| GET | `/auth/mode` | Public. Which sign-in the dashboard shows: `{ "mode": "password" \| "external", "signInUrl": string \| null }` (`Cache-Control: no-store`) |
|
|
70
|
+
| POST | `/auth/login` | Authenticate with username/password, receive JWT (501 in external mode) |
|
|
69
71
|
| GET | `/auth/me` | Get current user info from token |
|
|
70
72
|
|
|
71
73
|
### Status
|
|
@@ -104,6 +106,53 @@ The log buffer captures `console.log`/`warn`/`error` output. As a safety net, a
|
|
|
104
106
|
|---|---|---|
|
|
105
107
|
| GET | `/ws/clients` | List connected WebSocket clients |
|
|
106
108
|
|
|
109
|
+
### Sign in with the host app's session
|
|
110
|
+
|
|
111
|
+
The full setup (adapter, middleware order, permissions) is in [Use with your app's sign-in](../../README.md#use-with-your-apps-sign-in).
|
|
112
|
+
|
|
113
|
+
When the users plugin delegates authentication to your application (`setAuthAdapter`), the dashboard runs in **external** mode. The users plugin sets the server's `serverOptions.externalAuthentication` when it is mounted (`mountPlugin(usersPlugin)` or `createCliServer({ auth })`), and the admin plugin reads it on every request, so the mounting order does not matter.
|
|
114
|
+
|
|
115
|
+
- `GET /api/v1/qcli/auth/mode` answers `{ "mode": "external", "signInUrl": "<setSignInUrl>" }`. It is public, also on protected servers, so the dashboard can call it before anyone signs in. Otherwise it answers `"password"`.
|
|
116
|
+
- The dashboard hides its username/password form and shows "Sign in at `<signInUrl>`" with a Retry button (or tells users to sign in through the host application when no sign-in URL is set). Any 401 leads to that screen.
|
|
117
|
+
- `POST /api/v1/qcli/auth/login` signs no one in: it answers `501` with `code: "EXTERNAL_AUTH"`, a message pointing to the host's sign-in and `signInUrl`. The static admin credentials are never accepted in this mode.
|
|
118
|
+
- With `setAuthProvider(usersPlugin.serverAuth)`, admin routes authenticate the request through the users plugin (your adapter) and require `admin:access` (`isAdmin` grants it through the `admin` group).
|
|
119
|
+
|
|
120
|
+
The sign-in URL must be an absolute `http`/`https` URL or a root-relative path (`/sign-in`); anything else (for example `javascript:` or `//host`) makes `build()` throw.
|
|
121
|
+
|
|
122
|
+
**Handoff.** Send signed-in users to the dashboard with your bearer token in the URL fragment:
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
/qcli/admin/#token=<host bearer token>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
A fragment is never sent to servers or written to access logs. The dashboard reads it on startup, stores it as its admin token, removes it from the address bar (`history.replaceState`) and sends it as `Authorization: Bearer …` on every API call, where your external auth adapter validates it like any other request from your app.
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
// Host app: the adapter accepts the app's own JWT (verified by your middleware, which sets req.user).
|
|
132
|
+
const usersPlugin = new CliUsersBuilder()
|
|
133
|
+
.setAuthAdapter((req) => {
|
|
134
|
+
const principal = (req as any).user;
|
|
135
|
+
if (!principal) return null;
|
|
136
|
+
return { user: { id: principal.sub, name: principal.name, email: principal.email ?? '', groups: [], createdAt: 0, updatedAt: 0 }, isAdmin: principal.roles?.includes('admin') };
|
|
137
|
+
})
|
|
138
|
+
.build((msg) => eventSocketManager.broadcastMessage(msg));
|
|
139
|
+
|
|
140
|
+
const adminPlugin = new CliAdminBuilder()
|
|
141
|
+
.setAuthProvider(usersPlugin.serverAuth)
|
|
142
|
+
.setSignInUrl('/sign-in?returnUrl=%2Fadmin%2Fconsole')
|
|
143
|
+
.build({ registry, eventSocketManager, builder });
|
|
144
|
+
|
|
145
|
+
mountPlugin(adminPlugin);
|
|
146
|
+
mountPlugin(usersPlugin);
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
// Host front end: an "Open console" button for a signed-in admin.
|
|
151
|
+
window.location.href = `/qcli/admin/#token=${encodeURIComponent(accessToken)}`;
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
When the token expires, the next API call answers 401 and the dashboard shows the sign-in screen; after signing in again, the host repeats the handoff.
|
|
155
|
+
|
|
107
156
|
## Dashboard
|
|
108
157
|
|
|
109
158
|
The plugin includes a bundled SPA dashboard served at the built-in prefix (`/qcli/admin`). The dashboard is found in this order: the directory given to `setDashboardDir()`, a sibling `cli-server-dashboard/dist` build (development), the package's bundled `dashboard/` directory, and the `@qodalis/cli-server-dashboard` package if installed separately. The same order applies whether the plugin runs compiled or from source (`tsx`).
|