@flink-app/flink 2.0.0-alpha.96 → 2.0.0-alpha.98
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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,52 @@
|
|
|
1
1
|
# @flink-app/flink
|
|
2
2
|
|
|
3
|
+
## 2.0.0-alpha.98
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 2f4a132: feat: expose verified token on the request
|
|
8
|
+
|
|
9
|
+
The JWT auth plugin now populates `req.token` (the decoded, signature-verified
|
|
10
|
+
payload) and `req.rawToken` (the original token string) after successful
|
|
11
|
+
authentication. Handlers can read token claims such as `jti` directly instead of
|
|
12
|
+
re-extracting and re-decoding the bearer token with an unverified decode.
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
// Before
|
|
16
|
+
const authHeader = req.headers.authorization;
|
|
17
|
+
const bearer = authHeader?.startsWith("Bearer ") ? authHeader.slice(7) : undefined;
|
|
18
|
+
const decoded = bearer ? (jsonwebtoken.decode(bearer) as { jti?: string }) : null;
|
|
19
|
+
const sessionId = decoded?.jti ?? legacySessionId(req.user._id);
|
|
20
|
+
|
|
21
|
+
// After
|
|
22
|
+
const { jti } = (req.token as { jti?: string }) ?? {};
|
|
23
|
+
const sessionId = jti ?? legacySessionId(req.user._id);
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`token` / `rawToken` are added as optional fields on the core `FlinkRequest`
|
|
27
|
+
type, populated by auth plugins that have a token concept.
|
|
28
|
+
|
|
29
|
+
## 2.0.0-alpha.97
|
|
30
|
+
|
|
31
|
+
### Minor Changes
|
|
32
|
+
|
|
33
|
+
- eed6bc1: Pass host application context to auth plugins.
|
|
34
|
+
|
|
35
|
+
`FlinkAuthPlugin.authenticateRequest` now receives the host app's context as an optional third argument. Flink core supplies it on every authenticated request, so auth plugins can access repos/services without the caller wiring up a lazy accessor or maintaining a module-level mutable reference.
|
|
36
|
+
|
|
37
|
+
For `@flink-app/jwt-auth-plugin`, this means `getUser` receives the context directly:
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
jwtAuthPlugin({
|
|
41
|
+
getUser: async (tokenData, req, ctx) => {
|
|
42
|
+
const user = await ctx?.repos.userRepo.getById(tokenData._id);
|
|
43
|
+
return user ? { username: user.username, _id: user._id } : null;
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The `getContext` option previously added in alpha.96 is no longer needed and has been removed — remove it from your `jwtAuthPlugin({ … })` call. The third `ctx` parameter on `getUser` is optional, so callbacks that ignore it are unaffected.
|
|
49
|
+
|
|
3
50
|
## 2.0.0-alpha.96
|
|
4
51
|
|
|
5
52
|
### Patch Changes
|
package/dist/src/FlinkApp.js
CHANGED
|
@@ -1300,7 +1300,7 @@ var FlinkApp = /** @class */ (function () {
|
|
|
1300
1300
|
if (!this.auth) {
|
|
1301
1301
|
throw new Error("Attempting to authenticate request (".concat(req.method, " ").concat(req.path, ") but no authPlugin is set"));
|
|
1302
1302
|
}
|
|
1303
|
-
return [4 /*yield*/, this.auth.authenticateRequest(req, permissions)];
|
|
1303
|
+
return [4 /*yield*/, this.auth.authenticateRequest(req, permissions, this._ctx)];
|
|
1304
1304
|
case 1: return [2 /*return*/, _a.sent()];
|
|
1305
1305
|
}
|
|
1306
1306
|
});
|
|
@@ -93,11 +93,18 @@ export interface StreamWriter<T = any> {
|
|
|
93
93
|
* userPermissions is populated by auth plugins during authentication and contains
|
|
94
94
|
* the resolved permissions array based on the plugin's configuration (roles, dynamic
|
|
95
95
|
* roles, custom permissions, etc.)
|
|
96
|
+
*
|
|
97
|
+
* token / rawToken are populated by auth plugins that have a token concept (e.g. JWT).
|
|
98
|
+
* `token` is the decoded, signature-verified payload; `rawToken` is the original token
|
|
99
|
+
* string that authenticated the request (Bearer header or custom tokenExtractor output).
|
|
100
|
+
* Both are optional and only set once authentication succeeds.
|
|
96
101
|
*/
|
|
97
102
|
export type FlinkRequest<T = any, P = Params, Q = Query> = Request<P, any, T, Q> & {
|
|
98
103
|
reqId: string;
|
|
99
104
|
user?: any;
|
|
100
105
|
userPermissions?: string[];
|
|
106
|
+
token?: any;
|
|
107
|
+
rawToken?: string;
|
|
101
108
|
};
|
|
102
109
|
/**
|
|
103
110
|
* Route props to control routing.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FlinkRequest } from "../FlinkHttpHandler";
|
|
2
2
|
export interface FlinkAuthPlugin {
|
|
3
|
-
authenticateRequest: (req: FlinkRequest, permissions: string | string[]) => Promise<boolean>;
|
|
3
|
+
authenticateRequest: (req: FlinkRequest, permissions: string | string[], ctx?: any) => Promise<boolean>;
|
|
4
4
|
createToken: (payload: any, roles: string[]) => Promise<string>;
|
|
5
5
|
}
|
package/package.json
CHANGED
package/src/FlinkApp.ts
CHANGED
|
@@ -1580,7 +1580,7 @@ export class FlinkApp<C extends FlinkContext> {
|
|
|
1580
1580
|
if (!this.auth) {
|
|
1581
1581
|
throw new Error(`Attempting to authenticate request (${req.method} ${req.path}) but no authPlugin is set`);
|
|
1582
1582
|
}
|
|
1583
|
-
return await this.auth.authenticateRequest(req as FlinkRequest, permissions);
|
|
1583
|
+
return await this.auth.authenticateRequest(req as FlinkRequest, permissions, this._ctx);
|
|
1584
1584
|
}
|
|
1585
1585
|
|
|
1586
1586
|
public getRegisteredRoutes() {
|
package/src/FlinkHttpHandler.ts
CHANGED
|
@@ -104,11 +104,18 @@ export interface StreamWriter<T = any> {
|
|
|
104
104
|
* userPermissions is populated by auth plugins during authentication and contains
|
|
105
105
|
* the resolved permissions array based on the plugin's configuration (roles, dynamic
|
|
106
106
|
* roles, custom permissions, etc.)
|
|
107
|
+
*
|
|
108
|
+
* token / rawToken are populated by auth plugins that have a token concept (e.g. JWT).
|
|
109
|
+
* `token` is the decoded, signature-verified payload; `rawToken` is the original token
|
|
110
|
+
* string that authenticated the request (Bearer header or custom tokenExtractor output).
|
|
111
|
+
* Both are optional and only set once authentication succeeds.
|
|
107
112
|
*/
|
|
108
113
|
export type FlinkRequest<T = any, P = Params, Q = Query> = Request<P, any, T, Q> & {
|
|
109
114
|
reqId: string;
|
|
110
115
|
user?: any;
|
|
111
116
|
userPermissions?: string[]; // Resolved permissions from auth plugin
|
|
117
|
+
token?: any; // Decoded, verified token payload (set by auth plugin)
|
|
118
|
+
rawToken?: string; // Raw token string that authenticated the request
|
|
112
119
|
};
|
|
113
120
|
|
|
114
121
|
/**
|
|
@@ -3,7 +3,8 @@ import { FlinkRequest } from "../FlinkHttpHandler";
|
|
|
3
3
|
export interface FlinkAuthPlugin {
|
|
4
4
|
authenticateRequest: (
|
|
5
5
|
req: FlinkRequest,
|
|
6
|
-
permissions: string | string[]
|
|
6
|
+
permissions: string | string[],
|
|
7
|
+
ctx?: any
|
|
7
8
|
) => Promise<boolean>;
|
|
8
9
|
createToken: (payload: any, roles: string[]) => Promise<string>;
|
|
9
10
|
}
|