@wervt/nuxt 0.3.0 → 0.3.1

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/dist/module.js CHANGED
@@ -275,6 +275,10 @@ var module_default = defineNuxtModule({
275
275
  method: "get",
276
276
  handler: resolver.resolve("./runtime/server/user-route")
277
277
  });
278
+ if (nitroMajor >= 3) addServerHandler({
279
+ route: "/.well-known/oauth-protected-resource",
280
+ handler: resolver.resolve("./runtime/server/mcp-metadata")
281
+ });
278
282
  addPlugin({
279
283
  src: resolver.resolve("./runtime/app/plugins/user.client"),
280
284
  mode: "client"
@@ -17,7 +17,9 @@ declare module 'nuxt/schema' {
17
17
  }
18
18
  }
19
19
  export interface McpEndpoint {
20
- /** This app's `/mcp`, the audience its access tokens must carry. */
20
+ /** This app's origin, a resource too: tokens for the whole app (native apps) work on `/mcp`. */
21
+ app: string;
22
+ /** This app's `/mcp`, the audience MCP clients' access tokens carry. */
21
23
  resource: string;
22
24
  /** wervt's login as OAuth issuer, e.g. `https://auth.wervt.app/api/auth`. */
23
25
  issuer: string;
@@ -36,8 +38,8 @@ export declare const CORS: {
36
38
  'access-control-allow-headers': string;
37
39
  'access-control-max-age': string;
38
40
  };
39
- /** RFC 9728: tells MCP clients which login issues tokens for `/mcp`. */
40
- export declare function protectedResourceMetadata(endpoint: McpEndpoint): {
41
+ /** RFC 9728: tells clients which login issues tokens for `resource` (`/mcp` or the app). */
42
+ export declare function protectedResourceMetadata(endpoint: McpEndpoint, resource?: string): {
41
43
  resource: string;
42
44
  authorization_servers: string[];
43
45
  bearer_methods_supported: string[];
@@ -12,6 +12,7 @@ function mcpEndpoint(event) {
12
12
  if (!authUrl) return void 0;
13
13
  const appUrl = trimSlash(process.env.WERVT_APP_URL ?? getRequestURL(event).origin);
14
14
  return {
15
+ app: appUrl,
15
16
  resource: `${appUrl}/mcp`,
16
17
  issuer: `${trimSlash(authUrl)}/api/auth`,
17
18
  metadataUrl: `${appUrl}/.well-known/oauth-protected-resource/mcp`
@@ -24,10 +25,10 @@ const CORS = {
24
25
  "access-control-allow-headers": "*",
25
26
  "access-control-max-age": "86400"
26
27
  };
27
- /** RFC 9728: tells MCP clients which login issues tokens for `/mcp`. */
28
- function protectedResourceMetadata(endpoint) {
28
+ /** RFC 9728: tells clients which login issues tokens for `resource` (`/mcp` or the app). */
29
+ function protectedResourceMetadata(endpoint, resource = endpoint.resource) {
29
30
  return {
30
- resource: endpoint.resource,
31
+ resource,
31
32
  authorization_servers: [endpoint.issuer],
32
33
  bearer_methods_supported: ["header"],
33
34
  scopes_supported: [
@@ -36,7 +37,7 @@ function protectedResourceMetadata(endpoint) {
36
37
  "email",
37
38
  "offline_access"
38
39
  ],
39
- resource_name: new URL(endpoint.resource).hostname.split(".")[0]
40
+ resource_name: new URL(resource).hostname.split(".")[0]
40
41
  };
41
42
  }
42
43
  /**
@@ -69,7 +70,7 @@ async function verifyAccessToken(token, endpoint) {
69
70
  try {
70
71
  const { payload } = await jwtVerify(token, keySet(endpoint.issuer), {
71
72
  issuer: endpoint.issuer,
72
- audience: endpoint.resource,
73
+ audience: [endpoint.resource, endpoint.app],
73
74
  requiredClaims: ["exp", "sub"],
74
75
  clockTolerance: 5
75
76
  });
@@ -1,5 +1,5 @@
1
1
  import { CORS, mcpEndpoint, protectedResourceMetadata } from "./mcp-auth.js";
2
- import { defineEventHandler } from "nuxt/server";
2
+ import { defineEventHandler, getRequestURL } from "nuxt/server";
3
3
  //#region src/runtime/server/mcp-metadata.ts
4
4
  var mcp_metadata_default = defineEventHandler((event) => {
5
5
  const endpoint = mcpEndpoint(event);
@@ -8,7 +8,8 @@ var mcp_metadata_default = defineEventHandler((event) => {
8
8
  headers: CORS
9
9
  });
10
10
  if (!endpoint) return Response.json({ error: "No login configured." }, { status: 404 });
11
- return Response.json(protectedResourceMetadata(endpoint), { headers: CORS });
11
+ const mcp = getRequestURL(event).pathname.endsWith("/mcp");
12
+ return Response.json(protectedResourceMetadata(endpoint, mcp ? endpoint.resource : endpoint.app), { headers: CORS });
12
13
  });
13
14
  //#endregion
14
15
  export { mcp_metadata_default as default };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wervt/nuxt",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Nuxt module for apps hosted on wervt: database, live data, MCP and runtime setup.",
5
5
  "keywords": [
6
6
  "drizzle",