@better-auth/oauth-provider 1.5.0-beta.2 → 1.5.0-beta.20
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/LICENSE.md +15 -12
- package/README.md +17 -0
- package/dist/client-resource.d.mts +6 -8
- package/dist/client-resource.mjs +20 -6
- package/dist/client-resource.mjs.map +1 -0
- package/dist/client.d.mts +4 -3
- package/dist/client.mjs +3 -2
- package/dist/client.mjs.map +1 -0
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +679 -529
- package/dist/index.mjs.map +1 -0
- package/dist/{oauth-BrFoF22H.d.mts → oauth-CAVzHW54.d.mts} +108 -19
- package/dist/{oauth-C1OnEiU-.d.mts → oauth-DJ7bwizI.d.mts} +56 -13
- package/dist/{utils-CSiY9oUk.mjs → utils-DqGkkPq2.mjs} +65 -21
- package/dist/utils-DqGkkPq2.mjs.map +1 -0
- package/package.json +38 -35
package/LICENSE.md
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
The MIT License (MIT)
|
|
2
2
|
Copyright (c) 2024 - present, Bereket Engida
|
|
3
3
|
|
|
4
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
5
|
-
and associated documentation files (the
|
|
6
|
-
including without limitation the rights to
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
5
|
+
this software and associated documentation files (the “Software”), to deal in
|
|
6
|
+
the Software without restriction, including without limitation the rights to
|
|
7
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
8
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
9
|
+
subject to the following conditions:
|
|
9
10
|
|
|
10
|
-
The above copyright notice and this permission notice shall be included in all
|
|
11
|
-
substantial portions of the Software.
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
copies or substantial portions of the Software.
|
|
12
13
|
|
|
13
|
-
THE SOFTWARE IS PROVIDED
|
|
14
|
-
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
16
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
17
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
18
|
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
19
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
20
|
+
DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Better Auth OAuth Provider Plugin
|
|
2
|
+
|
|
3
|
+
OAuth provider plugin for [Better Auth](https://www.better-auth.com) — turn your application into an OAuth 2.0 provider.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @better-auth/oauth-provider
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Documentation
|
|
12
|
+
|
|
13
|
+
For full documentation, visit [better-auth.com/docs/plugins/oauth-provider](https://www.better-auth.com/docs/plugins/oauth-provider).
|
|
14
|
+
|
|
15
|
+
## License
|
|
16
|
+
|
|
17
|
+
MIT
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ResourceServerMetadata } from "./oauth-
|
|
1
|
+
import { a as ResourceServerMetadata } from "./oauth-CAVzHW54.mjs";
|
|
2
2
|
import { JWTPayload, JWTVerifyOptions } from "jose";
|
|
3
3
|
import { Auth } from "better-auth/types";
|
|
4
4
|
|
|
@@ -47,23 +47,20 @@ type VerifyAccessTokenAuthOpts = {
|
|
|
47
47
|
verifyOptions?: JWTVerifyOptions & Required<Pick<JWTVerifyOptions, "audience">>;
|
|
48
48
|
scopes?: string[];
|
|
49
49
|
jwksUrl?: string;
|
|
50
|
-
remoteVerify?: VerifyAccessTokenRemote;
|
|
51
|
-
/** Maps non-url (ie urn, client) resources to resource_metadata */
|
|
50
|
+
remoteVerify?: VerifyAccessTokenRemote; /** Maps non-url (ie urn, client) resources to resource_metadata */
|
|
52
51
|
resourceMetadataMappings?: Record<string, string>;
|
|
53
52
|
};
|
|
54
53
|
type VerifyAccessTokenNoAuthOpts = {
|
|
55
54
|
verifyOptions: JWTVerifyOptions & Required<Pick<JWTVerifyOptions, "audience" | "issuer">>;
|
|
56
55
|
scopes?: string[];
|
|
57
56
|
jwksUrl: string;
|
|
58
|
-
remoteVerify?: VerifyAccessTokenRemote;
|
|
59
|
-
/** Maps non-url (ie urn, client) resources to resource_metadata */
|
|
57
|
+
remoteVerify?: VerifyAccessTokenRemote; /** Maps non-url (ie urn, client) resources to resource_metadata */
|
|
60
58
|
resourceMetadataMappings?: Record<string, string>;
|
|
61
59
|
} | {
|
|
62
60
|
verifyOptions: JWTVerifyOptions & Required<Pick<JWTVerifyOptions, "audience" | "issuer">>;
|
|
63
61
|
scopes?: string[];
|
|
64
62
|
jwksUrl?: string;
|
|
65
|
-
remoteVerify: VerifyAccessTokenRemote;
|
|
66
|
-
/** Maps non-url (ie urn, client) resources to resource_metadata */
|
|
63
|
+
remoteVerify: VerifyAccessTokenRemote; /** Maps non-url (ie urn, client) resources to resource_metadata */
|
|
67
64
|
resourceMetadataMappings?: Record<string, string>;
|
|
68
65
|
};
|
|
69
66
|
type ProtectedResourceMetadataOutput<T> = T extends Auth ? (overrides?: Partial<ResourceServerMetadata>, opts?: {
|
|
@@ -78,4 +75,5 @@ type ProtectedResourceMetadataOutput<T> = T extends Auth ? (overrides?: Partial<
|
|
|
78
75
|
externalScopes?: string[];
|
|
79
76
|
}) => Promise<ResourceServerMetadata>;
|
|
80
77
|
//#endregion
|
|
81
|
-
export { VerifyAccessTokenRemote, oauthProviderResourceClient };
|
|
78
|
+
export { VerifyAccessTokenRemote, oauthProviderResourceClient };
|
|
79
|
+
//# sourceMappingURL=client-resource.d.mts.map
|
package/dist/client-resource.mjs
CHANGED
|
@@ -1,21 +1,32 @@
|
|
|
1
|
-
import { a as getJwtPlugin,
|
|
1
|
+
import { a as getJwtPlugin, m as handleMcpErrors, o as getOAuthProviderPlugin } from "./utils-DqGkkPq2.mjs";
|
|
2
2
|
import { verifyAccessToken } from "better-auth/oauth2";
|
|
3
3
|
import { APIError } from "better-call";
|
|
4
|
-
import { BetterAuthError } from "@better-auth/core/error";
|
|
5
4
|
import { logger } from "@better-auth/core/env";
|
|
5
|
+
import { BetterAuthError } from "@better-auth/core/error";
|
|
6
6
|
|
|
7
7
|
//#region src/client-resource.ts
|
|
8
8
|
const oauthProviderResourceClient = (auth) => {
|
|
9
|
-
|
|
10
|
-
const
|
|
9
|
+
let oauthProviderPlugin;
|
|
10
|
+
const getOauthProviderPlugin = async () => {
|
|
11
|
+
if (!oauthProviderPlugin) oauthProviderPlugin = auth ? getOAuthProviderPlugin(await auth.$context) : void 0;
|
|
12
|
+
return oauthProviderPlugin;
|
|
13
|
+
};
|
|
14
|
+
let jwtPlugin;
|
|
15
|
+
const getJwtPluginOptions = async () => {
|
|
16
|
+
if (!jwtPlugin) jwtPlugin = auth && !(await getOauthProviderPlugin())?.options?.disableJwtPlugin ? getJwtPlugin(await auth.$context) : void 0;
|
|
17
|
+
return jwtPlugin?.options;
|
|
18
|
+
};
|
|
19
|
+
const getAuthorizationServer = async () => {
|
|
20
|
+
return (await getJwtPluginOptions())?.jwt?.issuer ?? authServerBaseUrl;
|
|
21
|
+
};
|
|
11
22
|
const authServerBaseUrl = auth?.options.baseURL;
|
|
12
23
|
const authServerBasePath = auth?.options.basePath;
|
|
13
|
-
const authorizationServer = jwtPluginOptions?.jwt?.issuer ?? authServerBaseUrl;
|
|
14
24
|
return {
|
|
15
25
|
id: "oauth-provider-resource-client",
|
|
16
26
|
getActions() {
|
|
17
27
|
return {
|
|
18
28
|
verifyAccessToken: (async (token, opts) => {
|
|
29
|
+
const jwtPluginOptions = await getJwtPluginOptions();
|
|
19
30
|
const audience = opts?.verifyOptions?.audience ?? authServerBaseUrl;
|
|
20
31
|
const issuer = opts?.verifyOptions?.issuer ?? jwtPluginOptions?.jwt?.issuer ?? authServerBaseUrl;
|
|
21
32
|
if (!audience) throw Error("please define opts.verifyOptions.audience");
|
|
@@ -43,6 +54,7 @@ const oauthProviderResourceClient = (auth) => {
|
|
|
43
54
|
}),
|
|
44
55
|
getProtectedResourceMetadata: (async (overrides, opts) => {
|
|
45
56
|
const resource = overrides?.resource ?? authServerBaseUrl;
|
|
57
|
+
const oauthProviderOptions = (await getOauthProviderPlugin())?.options;
|
|
46
58
|
if (!resource) throw Error("missing required resource");
|
|
47
59
|
if (oauthProviderOptions?.scopes && opts?.externalScopes && (overrides?.authorization_servers?.length ?? 0) <= 1) throw new BetterAuthError("external scopes should not be provided with one authorization server");
|
|
48
60
|
if (overrides?.scopes_supported) {
|
|
@@ -60,6 +72,7 @@ const oauthProviderResourceClient = (auth) => {
|
|
|
60
72
|
if (!allValidScopes.has(sc)) throw new BetterAuthError(`Unsupported scope ${sc}. If external, please add to "externalScopes"`);
|
|
61
73
|
}
|
|
62
74
|
}
|
|
75
|
+
const authorizationServer = await getAuthorizationServer();
|
|
63
76
|
return {
|
|
64
77
|
resource,
|
|
65
78
|
authorization_servers: authorizationServer ? [authorizationServer] : void 0,
|
|
@@ -72,4 +85,5 @@ const oauthProviderResourceClient = (auth) => {
|
|
|
72
85
|
};
|
|
73
86
|
|
|
74
87
|
//#endregion
|
|
75
|
-
export { oauthProviderResourceClient };
|
|
88
|
+
export { oauthProviderResourceClient };
|
|
89
|
+
//# sourceMappingURL=client-resource.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-resource.mjs","names":[],"sources":["../src/client-resource.ts"],"sourcesContent":["import { logger } from \"@better-auth/core/env\";\nimport { BetterAuthError } from \"@better-auth/core/error\";\nimport { verifyAccessToken } from \"better-auth/oauth2\";\nimport type { Auth, BetterAuthClientPlugin } from \"better-auth/types\";\nimport { APIError } from \"better-call\";\nimport type { JWTPayload, JWTVerifyOptions } from \"jose\";\nimport { handleMcpErrors } from \"./mcp\";\nimport type { ResourceServerMetadata } from \"./types/oauth\";\nimport { getJwtPlugin, getOAuthProviderPlugin } from \"./utils\";\n\nexport const oauthProviderResourceClient = <T extends Auth | undefined>(\n\tauth?: T,\n) => {\n\tlet oauthProviderPlugin:\n\t\t| ReturnType<typeof getOAuthProviderPlugin>\n\t\t| undefined;\n\tconst getOauthProviderPlugin = async () => {\n\t\tif (!oauthProviderPlugin) {\n\t\t\toauthProviderPlugin = auth\n\t\t\t\t? getOAuthProviderPlugin(await auth.$context)\n\t\t\t\t: undefined;\n\t\t}\n\t\treturn oauthProviderPlugin;\n\t};\n\tlet jwtPlugin: ReturnType<typeof getJwtPlugin> | undefined;\n\tconst getJwtPluginOptions = async () => {\n\t\tif (!jwtPlugin) {\n\t\t\tjwtPlugin =\n\t\t\t\tauth && !(await getOauthProviderPlugin())?.options?.disableJwtPlugin\n\t\t\t\t\t? getJwtPlugin(await auth.$context)\n\t\t\t\t\t: undefined;\n\t\t}\n\t\treturn jwtPlugin?.options;\n\t};\n\tconst getAuthorizationServer = async () => {\n\t\tconst jwtPluginOptions = await getJwtPluginOptions();\n\t\treturn jwtPluginOptions?.jwt?.issuer ?? authServerBaseUrl;\n\t};\n\tconst authServerBaseUrl = auth?.options.baseURL;\n\tconst authServerBasePath = auth?.options.basePath;\n\n\treturn {\n\t\tid: \"oauth-provider-resource-client\",\n\t\tgetActions() {\n\t\t\treturn {\n\t\t\t\t/**\n\t\t\t\t * Performs verification of an access token for your APIs. Can perform\n\t\t\t\t * local verification using `jwksUrl` by default. Can also be configured\n\t\t\t\t * for remote introspection using `remoteVerify` if a confidential client\n\t\t\t\t * is set up for this API.\n\t\t\t\t *\n\t\t\t\t * The optional auth parameter can fill known values automatically.\n\t\t\t\t */\n\t\t\t\tverifyAccessToken: (async (\n\t\t\t\t\ttoken: string | undefined,\n\t\t\t\t\topts?: {\n\t\t\t\t\t\tverifyOptions?: JWTVerifyOptions &\n\t\t\t\t\t\t\tRequired<Pick<JWTVerifyOptions, \"audience\" | \"issuer\">>;\n\t\t\t\t\t\tscopes?: string[];\n\t\t\t\t\t\tjwksUrl?: string;\n\t\t\t\t\t\tremoteVerify?: VerifyAccessTokenRemote;\n\t\t\t\t\t\t/** Maps non-url (ie urn, client) resources to resource_metadata */\n\t\t\t\t\t\tresourceMetadataMappings?: Record<string, string>;\n\t\t\t\t\t},\n\t\t\t\t): Promise<JWTPayload> => {\n\t\t\t\t\tconst jwtPluginOptions = await getJwtPluginOptions();\n\t\t\t\t\tconst audience = opts?.verifyOptions?.audience ?? authServerBaseUrl;\n\t\t\t\t\tconst issuer =\n\t\t\t\t\t\topts?.verifyOptions?.issuer ??\n\t\t\t\t\t\tjwtPluginOptions?.jwt?.issuer ??\n\t\t\t\t\t\tauthServerBaseUrl;\n\t\t\t\t\tif (!audience) {\n\t\t\t\t\t\tthrow Error(\"please define opts.verifyOptions.audience\");\n\t\t\t\t\t}\n\t\t\t\t\tif (!issuer) {\n\t\t\t\t\t\tthrow Error(\"please define opts.verifyOptions.issuer\");\n\t\t\t\t\t}\n\t\t\t\t\tconst jwksUrl =\n\t\t\t\t\t\topts?.jwksUrl ??\n\t\t\t\t\t\tjwtPluginOptions?.jwks?.remoteUrl ??\n\t\t\t\t\t\t(authServerBaseUrl\n\t\t\t\t\t\t\t? `${authServerBaseUrl + (authServerBasePath ?? \"\")}${jwtPluginOptions?.jwks?.jwksPath ?? \"/jwks\"}`\n\t\t\t\t\t\t\t: undefined);\n\t\t\t\t\tconst introspectUrl =\n\t\t\t\t\t\topts?.remoteVerify?.introspectUrl ??\n\t\t\t\t\t\t(authServerBaseUrl\n\t\t\t\t\t\t\t? `${authServerBaseUrl}${authServerBasePath ?? \"\"}/oauth2/introspect`\n\t\t\t\t\t\t\t: undefined);\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif (!token?.length) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\tmessage: \"missing authorization header\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn await verifyAccessToken(token, {\n\t\t\t\t\t\t\t...opts,\n\t\t\t\t\t\t\tjwksUrl,\n\t\t\t\t\t\t\tverifyOptions: {\n\t\t\t\t\t\t\t\t...opts?.verifyOptions,\n\t\t\t\t\t\t\t\taudience,\n\t\t\t\t\t\t\t\tissuer,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tremoteVerify:\n\t\t\t\t\t\t\t\topts?.remoteVerify && introspectUrl\n\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\t...opts.remoteVerify,\n\t\t\t\t\t\t\t\t\t\t\tintrospectUrl,\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tthrow handleMcpErrors(error, audience, {\n\t\t\t\t\t\t\tresourceMetadataMappings: opts?.resourceMetadataMappings,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}) as VerifyAccessTokenOutput<T>,\n\t\t\t\t/**\n\t\t\t\t * An authorization server does not typically publish\n\t\t\t\t * the `/.well-known/oauth-protected-resource` themselves.\n\t\t\t\t * Thus, we provide a client-only endpoint to help set up\n\t\t\t\t * your protected resource metadata.\n\t\t\t\t *\n\t\t\t\t * The optional auth parameter can fill known values automatically.\n\t\t\t\t *\n\t\t\t\t * @see https://datatracker.ietf.org/doc/html/rfc8414#section-2\n\t\t\t\t */\n\t\t\t\tgetProtectedResourceMetadata: (async (\n\t\t\t\t\toverrides: Partial<ResourceServerMetadata> | undefined,\n\t\t\t\t\topts:\n\t\t\t\t\t\t| {\n\t\t\t\t\t\t\t\tsilenceWarnings?: {\n\t\t\t\t\t\t\t\t\toidcScopes?: boolean;\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\texternalScopes?: string[];\n\t\t\t\t\t\t }\n\t\t\t\t\t\t| undefined,\n\t\t\t\t): Promise<ResourceServerMetadata> => {\n\t\t\t\t\tconst resource = overrides?.resource ?? authServerBaseUrl;\n\t\t\t\t\tconst oauthProviderOptions = (await getOauthProviderPlugin())\n\t\t\t\t\t\t?.options;\n\t\t\t\t\tif (!resource) {\n\t\t\t\t\t\tthrow Error(\"missing required resource\");\n\t\t\t\t\t}\n\t\t\t\t\tif (\n\t\t\t\t\t\toauthProviderOptions?.scopes &&\n\t\t\t\t\t\topts?.externalScopes &&\n\t\t\t\t\t\t(overrides?.authorization_servers?.length ?? 0) <= 1\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new BetterAuthError(\n\t\t\t\t\t\t\t\"external scopes should not be provided with one authorization server\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\t// Resource server should not mention specific scopes\n\t\t\t\t\tif (overrides?.scopes_supported) {\n\t\t\t\t\t\tconst allValidScopes = new Set([\n\t\t\t\t\t\t\t...(oauthProviderOptions?.scopes ?? []),\n\t\t\t\t\t\t\t...(opts?.externalScopes ?? []),\n\t\t\t\t\t\t]);\n\t\t\t\t\t\tfor (const sc of overrides.scopes_supported) {\n\t\t\t\t\t\t\tif (sc === \"openid\") {\n\t\t\t\t\t\t\t\tthrow new BetterAuthError(\n\t\t\t\t\t\t\t\t\t\"Only the Auth Server should utilize the openid scope\",\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ([\"profile\", \"email\", \"phone\", \"address\"].includes(sc)) {\n\t\t\t\t\t\t\t\tif (!opts?.silenceWarnings?.oidcScopes) {\n\t\t\t\t\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t\t\t\t\t`\"${sc}\" is typically restricted for the authorization server, a resource server typically shouldn't handle this scope`,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!allValidScopes.has(sc)) {\n\t\t\t\t\t\t\t\tthrow new BetterAuthError(\n\t\t\t\t\t\t\t\t\t`Unsupported scope ${sc}. If external, please add to \"externalScopes\"`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst authorizationServer = await getAuthorizationServer();\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tresource,\n\t\t\t\t\t\tauthorization_servers: authorizationServer\n\t\t\t\t\t\t\t? [authorizationServer]\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t...overrides,\n\t\t\t\t\t};\n\t\t\t\t}) as ProtectedResourceMetadataOutput<T>,\n\t\t\t};\n\t\t},\n\t} satisfies BetterAuthClientPlugin;\n};\n\nexport interface VerifyAccessTokenRemote {\n\t/** Full url of the introspect endpoint. Should end with `/oauth2/introspect` */\n\tintrospectUrl: string;\n\t/** Client Secret */\n\tclientId: string;\n\t/** Client Secret */\n\tclientSecret: string;\n\t/**\n\t * Forces remote verification of a token.\n\t * This ensures attached session (if applicable)\n\t * is also still active.\n\t */\n\tforce?: boolean;\n}\n\ntype VerifyAccessTokenOutput<T> = T extends Auth\n\t? (\n\t\t\ttoken: string | undefined,\n\t\t\topts?: VerifyAccessTokenAuthOpts,\n\t\t) => Promise<JWTPayload>\n\t: (\n\t\t\ttoken: string | undefined,\n\t\t\topts: VerifyAccessTokenNoAuthOpts,\n\t\t) => Promise<JWTPayload>;\ntype VerifyAccessTokenAuthOpts = {\n\tverifyOptions?: JWTVerifyOptions &\n\t\tRequired<Pick<JWTVerifyOptions, \"audience\">>;\n\tscopes?: string[];\n\tjwksUrl?: string;\n\tremoteVerify?: VerifyAccessTokenRemote;\n\t/** Maps non-url (ie urn, client) resources to resource_metadata */\n\tresourceMetadataMappings?: Record<string, string>;\n};\ntype VerifyAccessTokenNoAuthOpts =\n\t| {\n\t\t\tverifyOptions: JWTVerifyOptions &\n\t\t\t\tRequired<Pick<JWTVerifyOptions, \"audience\" | \"issuer\">>;\n\t\t\tscopes?: string[];\n\t\t\tjwksUrl: string;\n\t\t\tremoteVerify?: VerifyAccessTokenRemote;\n\t\t\t/** Maps non-url (ie urn, client) resources to resource_metadata */\n\t\t\tresourceMetadataMappings?: Record<string, string>;\n\t }\n\t| {\n\t\t\tverifyOptions: JWTVerifyOptions &\n\t\t\t\tRequired<Pick<JWTVerifyOptions, \"audience\" | \"issuer\">>;\n\t\t\tscopes?: string[];\n\t\t\tjwksUrl?: string;\n\t\t\tremoteVerify: VerifyAccessTokenRemote;\n\t\t\t/** Maps non-url (ie urn, client) resources to resource_metadata */\n\t\t\tresourceMetadataMappings?: Record<string, string>;\n\t };\n\ntype ProtectedResourceMetadataOutput<T> = T extends Auth\n\t? (\n\t\t\toverrides?: Partial<ResourceServerMetadata>,\n\t\t\topts?: {\n\t\t\t\tsilenceWarnings?: {\n\t\t\t\t\toidcScopes?: boolean;\n\t\t\t\t};\n\t\t\t\texternalScopes?: string[];\n\t\t\t},\n\t\t) => Promise<ResourceServerMetadata>\n\t: (\n\t\t\toverrides: ResourceServerMetadata,\n\t\t\topts?: {\n\t\t\t\tsilenceWarnings?: {\n\t\t\t\t\toidcScopes?: boolean;\n\t\t\t\t};\n\t\t\t\texternalScopes?: string[];\n\t\t\t},\n\t\t) => Promise<ResourceServerMetadata>;\n"],"mappings":";;;;;;;AAUA,MAAa,+BACZ,SACI;CACJ,IAAI;CAGJ,MAAM,yBAAyB,YAAY;AAC1C,MAAI,CAAC,oBACJ,uBAAsB,OACnB,uBAAuB,MAAM,KAAK,SAAS,GAC3C;AAEJ,SAAO;;CAER,IAAI;CACJ,MAAM,sBAAsB,YAAY;AACvC,MAAI,CAAC,UACJ,aACC,QAAQ,EAAE,MAAM,wBAAwB,GAAG,SAAS,mBACjD,aAAa,MAAM,KAAK,SAAS,GACjC;AAEL,SAAO,WAAW;;CAEnB,MAAM,yBAAyB,YAAY;AAE1C,UADyB,MAAM,qBAAqB,GAC3B,KAAK,UAAU;;CAEzC,MAAM,oBAAoB,MAAM,QAAQ;CACxC,MAAM,qBAAqB,MAAM,QAAQ;AAEzC,QAAO;EACN,IAAI;EACJ,aAAa;AACZ,UAAO;IASN,oBAAoB,OACnB,OACA,SASyB;KACzB,MAAM,mBAAmB,MAAM,qBAAqB;KACpD,MAAM,WAAW,MAAM,eAAe,YAAY;KAClD,MAAM,SACL,MAAM,eAAe,UACrB,kBAAkB,KAAK,UACvB;AACD,SAAI,CAAC,SACJ,OAAM,MAAM,4CAA4C;AAEzD,SAAI,CAAC,OACJ,OAAM,MAAM,0CAA0C;KAEvD,MAAM,UACL,MAAM,WACN,kBAAkB,MAAM,cACvB,oBACE,GAAG,qBAAqB,sBAAsB,MAAM,kBAAkB,MAAM,YAAY,YACxF;KACJ,MAAM,gBACL,MAAM,cAAc,kBACnB,oBACE,GAAG,oBAAoB,sBAAsB,GAAG,sBAChD;AAEJ,SAAI;AACH,UAAI,CAAC,OAAO,OACX,OAAM,IAAI,SAAS,gBAAgB,EAClC,SAAS,gCACT,CAAC;AAEH,aAAO,MAAM,kBAAkB,OAAO;OACrC,GAAG;OACH;OACA,eAAe;QACd,GAAG,MAAM;QACT;QACA;QACA;OACD,cACC,MAAM,gBAAgB,gBACnB;QACA,GAAG,KAAK;QACR;QACA,GACA;OACJ,CAAC;cACM,OAAO;AACf,YAAM,gBAAgB,OAAO,UAAU,EACtC,0BAA0B,MAAM,0BAChC,CAAC;;;IAaJ,+BAA+B,OAC9B,WACA,SAQqC;KACrC,MAAM,WAAW,WAAW,YAAY;KACxC,MAAM,wBAAwB,MAAM,wBAAwB,GACzD;AACH,SAAI,CAAC,SACJ,OAAM,MAAM,4BAA4B;AAEzC,SACC,sBAAsB,UACtB,MAAM,mBACL,WAAW,uBAAuB,UAAU,MAAM,EAEnD,OAAM,IAAI,gBACT,uEACA;AAGF,SAAI,WAAW,kBAAkB;MAChC,MAAM,iBAAiB,IAAI,IAAI,CAC9B,GAAI,sBAAsB,UAAU,EAAE,EACtC,GAAI,MAAM,kBAAkB,EAAE,CAC9B,CAAC;AACF,WAAK,MAAM,MAAM,UAAU,kBAAkB;AAC5C,WAAI,OAAO,SACV,OAAM,IAAI,gBACT,uDACA;AAEF,WAAI;QAAC;QAAW;QAAS;QAAS;QAAU,CAAC,SAAS,GAAG,EACxD;YAAI,CAAC,MAAM,iBAAiB,WAC3B,QAAO,KACN,IAAI,GAAG,iHACP;;AAGH,WAAI,CAAC,eAAe,IAAI,GAAG,CAC1B,OAAM,IAAI,gBACT,qBAAqB,GAAG,+CACxB;;;KAKJ,MAAM,sBAAsB,MAAM,wBAAwB;AAE1D,YAAO;MACN;MACA,uBAAuB,sBACpB,CAAC,oBAAoB,GACrB;MACH,GAAG;MACH;;IAEF;;EAEF"}
|
package/dist/client.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "./oauth-
|
|
2
|
-
import {
|
|
1
|
+
import "./oauth-CAVzHW54.mjs";
|
|
2
|
+
import { n as oauthProvider } from "./oauth-DJ7bwizI.mjs";
|
|
3
3
|
import * as _better_fetch_fetch0 from "@better-fetch/fetch";
|
|
4
4
|
|
|
5
5
|
//#region src/client.d.ts
|
|
@@ -16,4 +16,5 @@ declare const oauthProviderClient: () => {
|
|
|
16
16
|
$InferServerPlugin: ReturnType<typeof oauthProvider>;
|
|
17
17
|
};
|
|
18
18
|
//#endregion
|
|
19
|
-
export { oauthProviderClient };
|
|
19
|
+
export { oauthProviderClient };
|
|
20
|
+
//# sourceMappingURL=client.d.mts.map
|
package/dist/client.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { safeJSONParse } from "@better-auth/core/utils";
|
|
1
|
+
import { safeJSONParse } from "@better-auth/core/utils/json";
|
|
2
2
|
|
|
3
3
|
//#region src/client.ts
|
|
4
4
|
function parseSignedQuery(search) {
|
|
@@ -35,4 +35,5 @@ const oauthProviderClient = () => {
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
//#endregion
|
|
38
|
-
export { oauthProviderClient };
|
|
38
|
+
export { oauthProviderClient };
|
|
39
|
+
//# sourceMappingURL=client.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.mjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["import { safeJSONParse } from \"@better-auth/core/utils/json\";\nimport type { BetterAuthClientPlugin } from \"better-auth/types\";\nimport type { oauthProvider } from \"./oauth\";\n\nfunction parseSignedQuery(search: string) {\n\tconst params = new URLSearchParams(search);\n\tif (params.has(\"sig\")) {\n\t\tconst signedParams = new URLSearchParams();\n\t\tfor (const [key, value] of params.entries()) {\n\t\t\tsignedParams.append(key, value);\n\t\t\tif (key === \"sig\") break;\n\t\t}\n\t\treturn signedParams.toString();\n\t}\n}\n\nexport const oauthProviderClient = () => {\n\treturn {\n\t\tid: \"oauth-provider-client\",\n\t\tfetchPlugins: [\n\t\t\t{\n\t\t\t\tid: \"oauth-provider-signin\",\n\t\t\t\tname: \"oauth-provider-signin\",\n\t\t\t\tdescription: \"Adds the current page query to oauth requests\",\n\t\t\t\thooks: {\n\t\t\t\t\tasync onRequest(ctx) {\n\t\t\t\t\t\tconst headers = ctx.headers;\n\t\t\t\t\t\tconst body =\n\t\t\t\t\t\t\ttypeof ctx.body === \"string\"\n\t\t\t\t\t\t\t\t? headers.get(\"content-type\") ===\n\t\t\t\t\t\t\t\t\t\"application/x-www-form-urlencoded\"\n\t\t\t\t\t\t\t\t\t? Object.fromEntries(new URLSearchParams(ctx.body))\n\t\t\t\t\t\t\t\t\t: safeJSONParse<Record<string, unknown>>(ctx.body ?? \"{}\")\n\t\t\t\t\t\t\t\t: ctx.body;\n\t\t\t\t\t\tif (body?.oauth_query) return;\n\t\t\t\t\t\tconst pathname =\n\t\t\t\t\t\t\ttypeof ctx.url === \"string\"\n\t\t\t\t\t\t\t\t? new URL(ctx.url).pathname\n\t\t\t\t\t\t\t\t: ctx.url.pathname;\n\t\t\t\t\t\t// Should only need to run for /sign-in/email, /sign-in/social, /sign-in/oauth2, /oauth2/consent, /oauth2/continue\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tpathname.endsWith(\"/sign-in/email\") ||\n\t\t\t\t\t\t\tpathname.endsWith(\"/sign-in/social\") ||\n\t\t\t\t\t\t\tpathname.endsWith(\"/sign-in/oauth2\") ||\n\t\t\t\t\t\t\tpathname.endsWith(\"/oauth2/consent\") ||\n\t\t\t\t\t\t\tpathname.endsWith(\"/oauth2/continue\")\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tctx.body = JSON.stringify({\n\t\t\t\t\t\t\t\t...body,\n\t\t\t\t\t\t\t\toauth_query:\n\t\t\t\t\t\t\t\t\ttypeof window !== \"undefined\"\n\t\t\t\t\t\t\t\t\t\t? parseSignedQuery(window?.location?.search)\n\t\t\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\t$InferServerPlugin: {} as ReturnType<typeof oauthProvider>,\n\t} satisfies BetterAuthClientPlugin;\n};\n"],"mappings":";;;AAIA,SAAS,iBAAiB,QAAgB;CACzC,MAAM,SAAS,IAAI,gBAAgB,OAAO;AAC1C,KAAI,OAAO,IAAI,MAAM,EAAE;EACtB,MAAM,eAAe,IAAI,iBAAiB;AAC1C,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,SAAS,EAAE;AAC5C,gBAAa,OAAO,KAAK,MAAM;AAC/B,OAAI,QAAQ,MAAO;;AAEpB,SAAO,aAAa,UAAU;;;AAIhC,MAAa,4BAA4B;AACxC,QAAO;EACN,IAAI;EACJ,cAAc,CACb;GACC,IAAI;GACJ,MAAM;GACN,aAAa;GACb,OAAO,EACN,MAAM,UAAU,KAAK;IACpB,MAAM,UAAU,IAAI;IACpB,MAAM,OACL,OAAO,IAAI,SAAS,WACjB,QAAQ,IAAI,eAAe,KAC5B,sCACE,OAAO,YAAY,IAAI,gBAAgB,IAAI,KAAK,CAAC,GACjD,cAAuC,IAAI,QAAQ,KAAK,GACzD,IAAI;AACR,QAAI,MAAM,YAAa;IACvB,MAAM,WACL,OAAO,IAAI,QAAQ,WAChB,IAAI,IAAI,IAAI,IAAI,CAAC,WACjB,IAAI,IAAI;AAEZ,QACC,SAAS,SAAS,iBAAiB,IACnC,SAAS,SAAS,kBAAkB,IACpC,SAAS,SAAS,kBAAkB,IACpC,SAAS,SAAS,kBAAkB,IACpC,SAAS,SAAS,mBAAmB,CAErC,KAAI,OAAO,KAAK,UAAU;KACzB,GAAG;KACH,aACC,OAAO,WAAW,cACf,iBAAiB,QAAQ,UAAU,OAAO,GAC1C;KACJ,CAAC;MAGJ;GACD,CACD;EACD,oBAAoB,EAAE;EACtB"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { _ as Awaitable, a as ResourceServerMetadata, c as OAuthConsent, d as OAuthRefreshToken, f as Prompt, g as VerificationValue, h as StoreTokenType, i as OIDCMetadata, l as OAuthOpaqueAccessToken, m as Scope, n as GrantType, o as AuthorizePrompt, p as SchemaClient, r as OAuthClient, s as OAuthAuthorizationQuery, t as AuthServerMetadata, u as OAuthOptions } from "./oauth-
|
|
2
|
-
import {
|
|
1
|
+
import { _ as Awaitable, a as ResourceServerMetadata, c as OAuthConsent, d as OAuthRefreshToken, f as Prompt, g as VerificationValue, h as StoreTokenType, i as OIDCMetadata, l as OAuthOpaqueAccessToken, m as Scope, n as GrantType, o as AuthorizePrompt, p as SchemaClient, r as OAuthClient, s as OAuthAuthorizationQuery, t as AuthServerMetadata, u as OAuthOptions } from "./oauth-CAVzHW54.mjs";
|
|
2
|
+
import { n as oauthProvider, t as getOAuthProviderState } from "./oauth-DJ7bwizI.mjs";
|
|
3
3
|
import { verifyAccessToken } from "better-auth/oauth2";
|
|
4
4
|
import { JWSAlgorithms, JwtOptions } from "better-auth/plugins";
|
|
5
5
|
import { JWTPayload } from "jose";
|
|
6
6
|
import { GenericEndpointContext } from "@better-auth/core";
|
|
7
7
|
|
|
8
8
|
//#region src/mcp.d.ts
|
|
9
|
-
|
|
10
9
|
/**
|
|
11
10
|
* A request middleware handler that checks and responds with
|
|
12
11
|
* a WWW-Authenticate header for unauthenticated responses.
|
|
@@ -14,9 +13,9 @@ import { GenericEndpointContext } from "@better-auth/core";
|
|
|
14
13
|
* @external
|
|
15
14
|
*/
|
|
16
15
|
declare const mcpHandler: (/** Resource is the same url as the audience */
|
|
16
|
+
|
|
17
17
|
verifyOptions: Parameters<typeof verifyAccessToken>[1], handler: (req: Request, jwt: JWTPayload) => Awaitable<Response>, opts?: {
|
|
18
|
-
/** Maps non-url (ie urn, client) resources to resource_metadata */
|
|
19
|
-
resourceMetadataMappings: Record<string, string>;
|
|
18
|
+
/** Maps non-url (ie urn, client) resources to resource_metadata */resourceMetadataMappings: Record<string, string>;
|
|
20
19
|
}) => (req: Request) => Promise<Response>;
|
|
21
20
|
//#endregion
|
|
22
21
|
//#region src/metadata.d.ts
|
|
@@ -62,4 +61,5 @@ declare const oauthProviderOpenIdConfigMetadata: <Auth extends {
|
|
|
62
61
|
headers?: HeadersInit;
|
|
63
62
|
}) => (_request: Request) => Promise<Response>;
|
|
64
63
|
//#endregion
|
|
65
|
-
export { AuthServerMetadata, AuthorizePrompt, OAuthAuthorizationQuery, OAuthClient, OAuthConsent, OAuthOpaqueAccessToken, OAuthOptions, OAuthRefreshToken, OIDCMetadata, Prompt, ResourceServerMetadata, SchemaClient, Scope, StoreTokenType, VerificationValue, authServerMetadata, mcpHandler, oauthProvider, oauthProviderAuthServerMetadata, oauthProviderOpenIdConfigMetadata, oidcServerMetadata };
|
|
64
|
+
export { AuthServerMetadata, AuthorizePrompt, OAuthAuthorizationQuery, OAuthClient, OAuthConsent, OAuthOpaqueAccessToken, OAuthOptions, OAuthRefreshToken, OIDCMetadata, Prompt, ResourceServerMetadata, SchemaClient, Scope, StoreTokenType, VerificationValue, authServerMetadata, getOAuthProviderState, mcpHandler, oauthProvider, oauthProviderAuthServerMetadata, oauthProviderOpenIdConfigMetadata, oidcServerMetadata };
|
|
65
|
+
//# sourceMappingURL=index.d.mts.map
|