@dudousxd/nestjs-agent-dashboard 0.8.0 → 0.9.0
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 +85 -2
- package/dist/server/index.cjs +1115 -217
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +149 -8
- package/dist/server/index.d.ts +149 -8
- package/dist/server/index.js +1072 -177
- package/dist/server/index.js.map +1 -1
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -39,8 +39,91 @@ The controllers are **path-relative and guard-frontable** — front `basePath`/`
|
|
|
39
39
|
|
|
40
40
|
```ts
|
|
41
41
|
AgentDashboardModule.forRoot({
|
|
42
|
-
basePath?: string;
|
|
43
|
-
apiBasePath?: string;
|
|
42
|
+
basePath?: string; // where the SPA is served. Default '/ai-gateway'
|
|
43
|
+
apiBasePath?: string; // where the JSON/SSE API is mounted. Default '<basePath>/api'
|
|
44
|
+
guards?: Type<CanActivate>[]; // bring-your-own auth — see "Console auth" below
|
|
45
|
+
dashboardAuth?: DashboardAuthOptions; // built-in login screen — see "Console auth" below
|
|
46
|
+
imports?: DynamicModule['imports'];
|
|
47
|
+
approvalActorRef?: (req) => string | undefined;
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Console auth
|
|
52
|
+
|
|
53
|
+
The console has no auth of its own by default — pick one of three postures, or combine them:
|
|
54
|
+
|
|
55
|
+
| Posture | When to use | Setup |
|
|
56
|
+
| ------- | ----------- | ----- |
|
|
57
|
+
| **Open** (default) | Local dev only. Never mount this way in production. | Omit both `guards` and `dashboardAuth`. |
|
|
58
|
+
| **`guards`** | You already have auth the console can reuse — an existing cookie-session guard, an SSO/OIDC session, a header your reverse proxy injects. | Pass guard classes; see below. |
|
|
59
|
+
| **`dashboardAuth`** | You have no ready-made guard for the console — e.g. your app authenticates with a header-only Bearer token a browser navigation can't attach — and want the simplest path to a protected console with zero SSO setup. | Pass `{ secret, login }`; see below. |
|
|
60
|
+
|
|
61
|
+
Both `guards` and `dashboardAuth` can be set together — **AND semantics**: a request must pass BOTH. `dashboardAuth`'s own gate runs first; a denied request never reaches your `guards`.
|
|
62
|
+
|
|
63
|
+
### Option A — `guards` (bring your own)
|
|
64
|
+
|
|
65
|
+
Front `basePath`/`apiBasePath` with a guard that reads YOUR app's session. A full-page navigation to `basePath` carries only cookies (never an `Authorization` header), so the guard must be able to authenticate from a cookie:
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import { CanActivate, ExecutionContext, Injectable, Module } from '@nestjs/common';
|
|
69
|
+
import { AgentDashboardModule } from '@dudousxd/nestjs-agent-dashboard';
|
|
70
|
+
|
|
71
|
+
@Injectable()
|
|
72
|
+
class ConsoleSessionGuard implements CanActivate {
|
|
73
|
+
constructor(private readonly sessions: SessionService) {}
|
|
74
|
+
|
|
75
|
+
async canActivate(context: ExecutionContext): Promise<boolean> {
|
|
76
|
+
const request = context.switchToHttp().getRequest();
|
|
77
|
+
const session = await this.sessions.verify(request.cookies?.appSession);
|
|
78
|
+
return session?.roles.includes('admin') ?? false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@Module({
|
|
83
|
+
imports: [
|
|
84
|
+
AgentDashboardModule.forRoot({
|
|
85
|
+
guards: [ConsoleSessionGuard],
|
|
86
|
+
imports: [SessionModule], // resolves ConsoleSessionGuard's own dependencies
|
|
87
|
+
}),
|
|
88
|
+
],
|
|
89
|
+
})
|
|
90
|
+
export class AppModule {}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Option B — `dashboardAuth` (built-in login screen)
|
|
94
|
+
|
|
95
|
+
Gates the console behind a stateless, signed session cookie (HMAC-SHA256, `node:crypto` only — no JWT dependency, no session store, mirrors `@dudousxd/nestjs-telescope`'s `dashboardAuth`). An unauthenticated page visit is redirected (302) to a built-in login form at `<basePath>/auth/login`; an unauthenticated API call gets `401`.
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
AgentDashboardModule.forRoot({
|
|
99
|
+
dashboardAuth: {
|
|
100
|
+
secret: process.env.AI_GATEWAY_AUTH_SECRET, // REQUIRED — 32+ bytes recommended. Missing => boot error.
|
|
101
|
+
ttl: '8h', // optional, default '8h'; sliding renewal past 50% TTL
|
|
102
|
+
login: async (username, password) => {
|
|
103
|
+
const user = await users.verify(username, password);
|
|
104
|
+
return user ? { id: user.id, name: user.name, roles: user.roles } : null; // null => generic failure
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Open `/ai-gateway`, enter the credentials, and you're in. Bad credentials get a **uniform** redirect back to the login page — the response is identical for an unknown user and a wrong password, so the endpoint never reveals which one was wrong. `POST <basePath>/auth/logout` clears the cookie.
|
|
111
|
+
|
|
112
|
+
Need the `login` hook to reach a DB (e.g. an `EntityManager`)? Use `forRootAsync` — `basePath`/`apiBasePath`/`guards` stay static (needed at module-build time for routing), only the auth config is resolved through DI:
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
AgentDashboardModule.forRootAsync({
|
|
116
|
+
imports: [DatabaseModule],
|
|
117
|
+
inject: [EntityManager],
|
|
118
|
+
useDashboardAuth: (em: EntityManager) => ({
|
|
119
|
+
secret: process.env.AI_GATEWAY_AUTH_SECRET,
|
|
120
|
+
login: async (username, password) => {
|
|
121
|
+
const admin = await em.findOne(AdminUser, { username });
|
|
122
|
+
return admin && (await admin.verifyPassword(password))
|
|
123
|
+
? { id: admin.id, name: admin.name, roles: ['admin'] }
|
|
124
|
+
: null;
|
|
125
|
+
},
|
|
126
|
+
}),
|
|
44
127
|
});
|
|
45
128
|
```
|
|
46
129
|
|