@better-auth/oauth-provider 1.6.11 → 1.6.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/dist/client-resource.d.mts +13 -6
- package/dist/client-resource.mjs +2 -2
- package/dist/client.d.mts +1 -1
- package/dist/client.mjs +1 -1
- package/dist/index.d.mts +3 -2
- package/dist/index.mjs +77 -56
- package/dist/{oauth-C4GaGx2I.d.mts → oauth-CUqnBdrR.d.mts} +6 -1
- package/dist/{oauth-BqWgUea8.d.mts → oauth-D74mBkw6.d.mts} +3 -1
- package/dist/{utils-LAthGy-x.mjs → utils-DoYEeMrg.mjs} +4 -2
- package/dist/{version-CRjaDWWg.mjs → version-MLrabwrK.mjs} +1 -1
- package/package.json +6 -6
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
import { s as ResourceServerMetadata } from "./oauth-
|
|
1
|
+
import { s as ResourceServerMetadata } from "./oauth-D74mBkw6.mjs";
|
|
2
2
|
import { JWTPayload, JWTVerifyOptions } from "jose";
|
|
3
|
-
import {
|
|
3
|
+
import { BetterAuthOptions } from "better-auth/types";
|
|
4
4
|
|
|
5
5
|
//#region src/client-resource.d.ts
|
|
6
|
-
|
|
6
|
+
type ResourceClientAuth = {
|
|
7
|
+
options: {
|
|
8
|
+
baseURL?: BetterAuthOptions["baseURL"];
|
|
9
|
+
basePath?: BetterAuthOptions["basePath"];
|
|
10
|
+
};
|
|
11
|
+
$context: Promise<unknown>;
|
|
12
|
+
};
|
|
13
|
+
declare const oauthProviderResourceClient: <T extends ResourceClientAuth | undefined = undefined>(auth?: T) => {
|
|
7
14
|
id: "oauth-provider-resource-client";
|
|
8
15
|
version: string;
|
|
9
16
|
getActions(): {
|
|
@@ -43,7 +50,7 @@ interface VerifyAccessTokenRemote {
|
|
|
43
50
|
*/
|
|
44
51
|
force?: boolean;
|
|
45
52
|
}
|
|
46
|
-
type VerifyAccessTokenOutput<T> = T extends
|
|
53
|
+
type VerifyAccessTokenOutput<T> = T extends undefined ? (token: string | undefined, opts: VerifyAccessTokenNoAuthOpts) => Promise<JWTPayload> : (token: string | undefined, opts?: VerifyAccessTokenAuthOpts) => Promise<JWTPayload>;
|
|
47
54
|
type VerifyAccessTokenAuthOpts = {
|
|
48
55
|
verifyOptions?: JWTVerifyOptions & Required<Pick<JWTVerifyOptions, "audience">>;
|
|
49
56
|
scopes?: string[];
|
|
@@ -64,12 +71,12 @@ type VerifyAccessTokenNoAuthOpts = {
|
|
|
64
71
|
remoteVerify: VerifyAccessTokenRemote; /** Maps non-url (ie urn, client) resources to resource_metadata */
|
|
65
72
|
resourceMetadataMappings?: Record<string, string>;
|
|
66
73
|
};
|
|
67
|
-
type ProtectedResourceMetadataOutput<T> = T extends
|
|
74
|
+
type ProtectedResourceMetadataOutput<T> = T extends undefined ? (overrides: ResourceServerMetadata, opts?: {
|
|
68
75
|
silenceWarnings?: {
|
|
69
76
|
oidcScopes?: boolean;
|
|
70
77
|
};
|
|
71
78
|
externalScopes?: string[];
|
|
72
|
-
}) => Promise<ResourceServerMetadata> : (overrides
|
|
79
|
+
}) => Promise<ResourceServerMetadata> : (overrides?: Partial<ResourceServerMetadata>, opts?: {
|
|
73
80
|
silenceWarnings?: {
|
|
74
81
|
oidcScopes?: boolean;
|
|
75
82
|
};
|
package/dist/client-resource.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as handleMcpErrors, a as getOAuthProviderPlugin, i as getJwtPlugin } from "./utils-
|
|
2
|
-
import { t as PACKAGE_VERSION } from "./version-
|
|
1
|
+
import { S as handleMcpErrors, a as getOAuthProviderPlugin, i as getJwtPlugin } from "./utils-DoYEeMrg.mjs";
|
|
2
|
+
import { t as PACKAGE_VERSION } from "./version-MLrabwrK.mjs";
|
|
3
3
|
import { verifyAccessToken } from "better-auth/oauth2";
|
|
4
4
|
import { APIError } from "better-call";
|
|
5
5
|
import { logger } from "@better-auth/core/env";
|
package/dist/client.d.mts
CHANGED
package/dist/client.mjs
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { _ as Scope, a as OAuthClient, b as Awaitable, c as TokenEndpointAuthMethod, d as OAuthConsent, f as OAuthOpaqueAccessToken, g as SchemaClient, h as Prompt, i as GrantType, l as AuthorizePrompt, m as OAuthRefreshToken, n as AuthServerMetadata, o as OIDCMetadata, p as OAuthOptions, r as BearerMethodsSupported, s as ResourceServerMetadata, t as AuthMethod, u as OAuthAuthorizationQuery, v as StoreTokenType, y as VerificationValue } from "./oauth-
|
|
2
|
-
import { n as oauthProvider, t as getOAuthProviderState } from "./oauth-
|
|
1
|
+
import { _ as Scope, a as OAuthClient, b as Awaitable, c as TokenEndpointAuthMethod, d as OAuthConsent, f as OAuthOpaqueAccessToken, g as SchemaClient, h as Prompt, i as GrantType, l as AuthorizePrompt, m as OAuthRefreshToken, n as AuthServerMetadata, o as OIDCMetadata, p as OAuthOptions, r as BearerMethodsSupported, s as ResourceServerMetadata, t as AuthMethod, u as OAuthAuthorizationQuery, v as StoreTokenType, y as VerificationValue } from "./oauth-D74mBkw6.mjs";
|
|
2
|
+
import { n as oauthProvider, t as getOAuthProviderState } from "./oauth-CUqnBdrR.mjs";
|
|
3
3
|
import { verifyAccessToken } from "better-auth/oauth2";
|
|
4
4
|
import { JWSAlgorithms, JwtOptions } from "better-auth/plugins";
|
|
5
5
|
import { JWTPayload } from "jose";
|
|
@@ -21,6 +21,7 @@ verifyOptions: Parameters<typeof verifyAccessToken>[1], handler: (req: Request,
|
|
|
21
21
|
//#region src/metadata.d.ts
|
|
22
22
|
declare function authServerMetadata(ctx: GenericEndpointContext, opts?: JwtOptions, overrides?: {
|
|
23
23
|
scopes_supported?: AuthServerMetadata["scopes_supported"];
|
|
24
|
+
dynamic_client_registration_supported?: boolean;
|
|
24
25
|
public_client_supported?: boolean;
|
|
25
26
|
grant_types_supported?: GrantType[];
|
|
26
27
|
jwt_disabled?: boolean;
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as mcpHandler, _ as signedQueryIssuedAtParam, b as validateClientCredentials, c as isPKCERequired, d as parsePrompt, f as postLoginClearedParam, g as searchParamsToQuery, h as resolveSubjectIdentifier, i as getJwtPlugin, l as normalizeTimestampValue, m as resolveSessionAuthTime, n as decryptStoredClientSecret, o as getSignedQueryIssuedAt, p as removePromptFromQuery, r as getClient, s as getStoredToken, t as basicToClientCredentials, u as parseClientMetadata, v as storeClientSecret, x as verifyOAuthQueryParams, y as storeToken } from "./utils-
|
|
2
|
-
import { t as PACKAGE_VERSION } from "./version-
|
|
1
|
+
import { C as mcpHandler, _ as signedQueryIssuedAtParam, b as validateClientCredentials, c as isPKCERequired, d as parsePrompt, f as postLoginClearedParam, g as searchParamsToQuery, h as resolveSubjectIdentifier, i as getJwtPlugin, l as normalizeTimestampValue, m as resolveSessionAuthTime, n as decryptStoredClientSecret, o as getSignedQueryIssuedAt, p as removePromptFromQuery, r as getClient, s as getStoredToken, t as basicToClientCredentials, u as parseClientMetadata, v as storeClientSecret, x as verifyOAuthQueryParams, y as storeToken } from "./utils-DoYEeMrg.mjs";
|
|
2
|
+
import { t as PACKAGE_VERSION } from "./version-MLrabwrK.mjs";
|
|
3
3
|
import { APIError, createAuthEndpoint, createAuthMiddleware, getOAuthState, getSessionFromCtx, sessionMiddleware } from "better-auth/api";
|
|
4
4
|
import { generateCodeChallenge, getJwks, verifyJwsAccessToken } from "better-auth/oauth2";
|
|
5
5
|
import { APIError as APIError$1 } from "better-call";
|
|
@@ -14,6 +14,7 @@ import { mergeSchema } from "better-auth/db";
|
|
|
14
14
|
import * as z from "zod";
|
|
15
15
|
import { signJWT, toExpJWT } from "better-auth/plugins";
|
|
16
16
|
import { SignJWT, compactVerify, createLocalJWKSet, decodeJwt } from "jose";
|
|
17
|
+
import { SafeUrlSchema } from "@better-auth/core/utils/redirect-uri";
|
|
17
18
|
//#region src/consent.ts
|
|
18
19
|
async function consentEndpoint(ctx, opts) {
|
|
19
20
|
const oauthRequest = await oAuthState.get();
|
|
@@ -174,11 +175,6 @@ async function postLogin(ctx, opts) {
|
|
|
174
175
|
}
|
|
175
176
|
//#endregion
|
|
176
177
|
//#region src/types/zod.ts
|
|
177
|
-
const DANGEROUS_SCHEMES = [
|
|
178
|
-
"javascript:",
|
|
179
|
-
"data:",
|
|
180
|
-
"vbscript:"
|
|
181
|
-
];
|
|
182
178
|
/**
|
|
183
179
|
* Runtime schema for OAuthAuthorizationQuery.
|
|
184
180
|
* Uses passthrough to tolerate fields added by future extensions (PAR, FPA, etc.)
|
|
@@ -214,34 +210,6 @@ const verificationValueSchema = z.object({
|
|
|
214
210
|
referenceId: z.string().optional(),
|
|
215
211
|
authTime: z.number().optional()
|
|
216
212
|
}).passthrough();
|
|
217
|
-
/**
|
|
218
|
-
* Reusable URL validation for OAuth redirect URIs.
|
|
219
|
-
* - Blocks dangerous schemes (javascript:, data:, vbscript:)
|
|
220
|
-
* - For http/https: requires HTTPS (HTTP allowed only for loopback hosts: 127.0.0.0/8, [::1], *.localhost per RFC 6761)
|
|
221
|
-
* - Allows custom schemes for mobile apps (e.g., myapp://callback)
|
|
222
|
-
*/
|
|
223
|
-
const SafeUrlSchema = z.url().superRefine((val, ctx) => {
|
|
224
|
-
if (!URL.canParse(val)) {
|
|
225
|
-
ctx.addIssue({
|
|
226
|
-
code: "custom",
|
|
227
|
-
message: "URL must be parseable",
|
|
228
|
-
fatal: true
|
|
229
|
-
});
|
|
230
|
-
return z.NEVER;
|
|
231
|
-
}
|
|
232
|
-
const u = new URL(val);
|
|
233
|
-
if (DANGEROUS_SCHEMES.includes(u.protocol)) {
|
|
234
|
-
ctx.addIssue({
|
|
235
|
-
code: "custom",
|
|
236
|
-
message: "URL cannot use javascript:, data:, or vbscript: scheme"
|
|
237
|
-
});
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
if (u.protocol === "http:" && !isLoopbackHost(u.host)) ctx.addIssue({
|
|
241
|
-
code: "custom",
|
|
242
|
-
message: "Redirect URI must use HTTPS (HTTP allowed only for loopback hosts)"
|
|
243
|
-
});
|
|
244
|
-
});
|
|
245
213
|
//#endregion
|
|
246
214
|
//#region src/userinfo.ts
|
|
247
215
|
/**
|
|
@@ -605,11 +573,7 @@ async function createUserTokens(ctx, opts, params) {
|
|
|
605
573
|
async function checkVerificationValue(ctx, opts, code, client_id, redirect_uri) {
|
|
606
574
|
const verification = await ctx.context.internalAdapter.consumeVerificationValue(await storeToken(opts.storeTokens, code, "authorization_code"));
|
|
607
575
|
if (!verification) throw new APIError("UNAUTHORIZED", {
|
|
608
|
-
error_description: "
|
|
609
|
-
error: "invalid_grant"
|
|
610
|
-
});
|
|
611
|
-
if (!verification.expiresAt || verification.expiresAt < /* @__PURE__ */ new Date()) throw new APIError("UNAUTHORIZED", {
|
|
612
|
-
error_description: "code expired",
|
|
576
|
+
error_description: "invalid code",
|
|
613
577
|
error: "invalid_grant"
|
|
614
578
|
});
|
|
615
579
|
let rawValue;
|
|
@@ -1237,6 +1201,28 @@ const publicSessionMiddleware = (opts) => createAuthMiddleware(async (ctx) => {
|
|
|
1237
1201
|
if (!await verifyOAuthQueryParams(query, ctx.context.secret)) throw new APIError("UNAUTHORIZED", { error: "invalid_signature" });
|
|
1238
1202
|
});
|
|
1239
1203
|
//#endregion
|
|
1204
|
+
//#region src/oauthClient/privileges.ts
|
|
1205
|
+
/**
|
|
1206
|
+
* Authorizes a client action against the configured `clientPrivileges` hook.
|
|
1207
|
+
*
|
|
1208
|
+
* This is the single authorization helper for every OAuth client mutation. The
|
|
1209
|
+
* create path enforces it at the shared creation chokepoint so that no
|
|
1210
|
+
* registration route can reach client persistence without it.
|
|
1211
|
+
*
|
|
1212
|
+
* @throws APIError UNAUTHORIZED when there is no session or the hook denies the action.
|
|
1213
|
+
* @throws APIError BAD_REQUEST when the request carries no headers.
|
|
1214
|
+
*/
|
|
1215
|
+
async function assertClientPrivileges(ctx, session, opts, action) {
|
|
1216
|
+
if (!session) throw new APIError("UNAUTHORIZED");
|
|
1217
|
+
if (!ctx.headers) throw new APIError("BAD_REQUEST");
|
|
1218
|
+
if (opts.clientPrivileges && !await opts.clientPrivileges({
|
|
1219
|
+
headers: ctx.headers,
|
|
1220
|
+
action,
|
|
1221
|
+
session: session.session,
|
|
1222
|
+
user: session.user
|
|
1223
|
+
})) throw new APIError("UNAUTHORIZED");
|
|
1224
|
+
}
|
|
1225
|
+
//#endregion
|
|
1240
1226
|
//#region src/register.ts
|
|
1241
1227
|
/**
|
|
1242
1228
|
* Resolves the auth method and type for unauthenticated DCR.
|
|
@@ -1331,6 +1317,9 @@ async function checkOAuthClient(client, opts, settings) {
|
|
|
1331
1317
|
async function createOAuthClientEndpoint(ctx, opts, settings) {
|
|
1332
1318
|
const body = ctx.body;
|
|
1333
1319
|
const session = await getSessionFromCtx(ctx);
|
|
1320
|
+
if (settings.isRegister) {
|
|
1321
|
+
if (session) await assertClientPrivileges(ctx, session, opts, "create");
|
|
1322
|
+
} else await assertClientPrivileges(ctx, session, opts, "create");
|
|
1334
1323
|
const isPublic = body.token_endpoint_auth_method === "none";
|
|
1335
1324
|
await checkOAuthClient(ctx.body, opts, settings);
|
|
1336
1325
|
const clientId = opts.generateClientId?.() || generateRandomString(32, "a-z", "A-Z");
|
|
@@ -1662,16 +1651,6 @@ async function rotateClientSecretEndpoint(ctx, opts) {
|
|
|
1662
1651
|
clientSecret: (opts.prefix?.clientSecret ?? "") + clientSecret
|
|
1663
1652
|
});
|
|
1664
1653
|
}
|
|
1665
|
-
async function assertClientPrivileges(ctx, session, opts, action) {
|
|
1666
|
-
if (!session) throw new APIError("UNAUTHORIZED");
|
|
1667
|
-
if (!ctx.headers) throw new APIError("BAD_REQUEST");
|
|
1668
|
-
if (opts.clientPrivileges && !await opts.clientPrivileges({
|
|
1669
|
-
headers: ctx.headers,
|
|
1670
|
-
action,
|
|
1671
|
-
session: session.session,
|
|
1672
|
-
user: session.user
|
|
1673
|
-
})) throw new APIError("UNAUTHORIZED");
|
|
1674
|
-
}
|
|
1675
1654
|
//#endregion
|
|
1676
1655
|
//#region src/oauthClient/index.ts
|
|
1677
1656
|
const adminCreateOAuthClient = (opts) => createAuthEndpoint("/admin/oauth2/create-client", {
|
|
@@ -1854,7 +1833,6 @@ const adminCreateOAuthClient = (opts) => createAuthEndpoint("/admin/oauth2/creat
|
|
|
1854
1833
|
}
|
|
1855
1834
|
}
|
|
1856
1835
|
}, async (ctx) => {
|
|
1857
|
-
await assertClientPrivileges(ctx, await getSessionFromCtx(ctx), opts, "create");
|
|
1858
1836
|
return createOAuthClientEndpoint(ctx, opts, { isRegister: false });
|
|
1859
1837
|
});
|
|
1860
1838
|
const createOAuthClient = (opts) => createAuthEndpoint("/oauth2/create-client", {
|
|
@@ -2024,7 +2002,6 @@ const createOAuthClient = (opts) => createAuthEndpoint("/oauth2/create-client",
|
|
|
2024
2002
|
} }
|
|
2025
2003
|
} }
|
|
2026
2004
|
}, async (ctx) => {
|
|
2027
|
-
await assertClientPrivileges(ctx, await getSessionFromCtx(ctx), opts, "create");
|
|
2028
2005
|
return createOAuthClientEndpoint(ctx, opts, { isRegister: false });
|
|
2029
2006
|
});
|
|
2030
2007
|
const getOAuthClient = (opts) => createAuthEndpoint("/oauth2/get-client", {
|
|
@@ -2228,12 +2205,12 @@ async function updateConsentEndpoint(ctx, opts) {
|
|
|
2228
2205
|
error_description: "no consent",
|
|
2229
2206
|
error: "not_found"
|
|
2230
2207
|
});
|
|
2208
|
+
if (consent.userId !== session.user.id) throw new APIError("UNAUTHORIZED");
|
|
2231
2209
|
const client = await getClient(ctx, opts, consent.clientId);
|
|
2232
|
-
if (!
|
|
2233
|
-
error_description: "
|
|
2210
|
+
if (!client) throw new APIError("NOT_FOUND", {
|
|
2211
|
+
error_description: "client not found",
|
|
2234
2212
|
error: "not_found"
|
|
2235
2213
|
});
|
|
2236
|
-
if (consent.userId !== session.user.id) throw new APIError("UNAUTHORIZED");
|
|
2237
2214
|
const allowedScopes = client?.scopes ?? opts.scopes ?? [];
|
|
2238
2215
|
const updates = ctx.body.update;
|
|
2239
2216
|
const scopes = updates.scopes;
|
|
@@ -2831,6 +2808,47 @@ const oauthProvider = (options) => {
|
|
|
2831
2808
|
if (opts.grantTypes && opts.grantTypes.includes("refresh_token") && !opts.grantTypes.includes("authorization_code")) throw new BetterAuthError("refresh_token grant requires authorization_code grant");
|
|
2832
2809
|
if (opts.disableJwtPlugin && (opts.storeClientSecret === "hashed" || typeof opts.storeClientSecret === "object" && "hash" in opts.storeClientSecret)) throw new BetterAuthError("unable to store hashed secrets because id tokens will be signed with secret");
|
|
2833
2810
|
if (!opts.disableJwtPlugin && (opts.storeClientSecret === "encrypted" || typeof opts.storeClientSecret === "object" && ("encrypt" in opts.storeClientSecret || "decrypt" in opts.storeClientSecret))) throw new BetterAuthError("encryption method not recommended, please use 'hashed' or the 'hash' function");
|
|
2811
|
+
const handleIssuerMetadataRequest = async (request, ctx) => {
|
|
2812
|
+
const requestPathname = new URL(request.url).pathname;
|
|
2813
|
+
const requestPath = ctx.options.advanced?.skipTrailingSlashes ? requestPathname.replace(/\/+$/, "") || "/" : requestPathname;
|
|
2814
|
+
const issuer = opts.disableJwtPlugin ? ctx.baseURL : getJwtPlugin(ctx)?.options?.jwt?.issuer ?? ctx.baseURL;
|
|
2815
|
+
let issuerPath = "/";
|
|
2816
|
+
try {
|
|
2817
|
+
issuerPath = new URL(issuer).pathname.replace(/\/$/, "") || "";
|
|
2818
|
+
} catch {
|
|
2819
|
+
issuerPath = new URL(ctx.baseURL).pathname.replace(/\/$/, "") || "";
|
|
2820
|
+
}
|
|
2821
|
+
const endpointCtx = { context: ctx };
|
|
2822
|
+
const authServerMetadataPaths = new Set([`/.well-known/oauth-authorization-server${issuerPath}`, `${issuerPath}/.well-known/oauth-authorization-server`]);
|
|
2823
|
+
const openIdConfigPath = `${issuerPath}/.well-known/openid-configuration`;
|
|
2824
|
+
const isAuthServerMetadataRequest = authServerMetadataPaths.has(requestPath);
|
|
2825
|
+
const isOpenIdConfigRequest = opts.scopes?.includes("openid") && requestPath === openIdConfigPath;
|
|
2826
|
+
const createMetadataResponse = (metadata) => {
|
|
2827
|
+
const response = metadataResponse(metadata);
|
|
2828
|
+
if (request.method === "HEAD") return new Response(null, {
|
|
2829
|
+
status: response.status,
|
|
2830
|
+
headers: response.headers
|
|
2831
|
+
});
|
|
2832
|
+
return response;
|
|
2833
|
+
};
|
|
2834
|
+
if (isAuthServerMetadataRequest || isOpenIdConfigRequest) {
|
|
2835
|
+
if (request.method !== "GET" && request.method !== "HEAD") return { response: new Response(null, {
|
|
2836
|
+
status: 405,
|
|
2837
|
+
headers: { Allow: "GET, HEAD" }
|
|
2838
|
+
}) };
|
|
2839
|
+
}
|
|
2840
|
+
if (isAuthServerMetadataRequest) {
|
|
2841
|
+
if (opts.scopes?.includes("openid")) return { response: createMetadataResponse(oidcServerMetadata(endpointCtx, opts)) };
|
|
2842
|
+
return { response: createMetadataResponse(authServerMetadata(endpointCtx, opts.disableJwtPlugin ? void 0 : getJwtPlugin(ctx)?.options, {
|
|
2843
|
+
scopes_supported: opts.advertisedMetadata?.scopes_supported ?? opts.scopes,
|
|
2844
|
+
dynamic_client_registration_supported: opts.allowDynamicClientRegistration,
|
|
2845
|
+
public_client_supported: opts.allowUnauthenticatedClientRegistration,
|
|
2846
|
+
grant_types_supported: opts.grantTypes,
|
|
2847
|
+
jwt_disabled: opts.disableJwtPlugin
|
|
2848
|
+
})) };
|
|
2849
|
+
}
|
|
2850
|
+
if (isOpenIdConfigRequest) return { response: createMetadataResponse(oidcServerMetadata(endpointCtx, opts)) };
|
|
2851
|
+
};
|
|
2834
2852
|
return {
|
|
2835
2853
|
id: "oauth-provider",
|
|
2836
2854
|
version: PACKAGE_VERSION,
|
|
@@ -2852,6 +2870,7 @@ const oauthProvider = (options) => {
|
|
|
2852
2870
|
if (!opts.silenceWarnings?.openidConfig && ctx.options.basePath !== issuerPath && opts.scopes?.includes("openid")) logger.warn(`Please ensure '${issuerPath}${issuerPath.endsWith("/") ? "" : "/"}.well-known/openid-configuration' exists. Upon completion, clear with silenceWarnings.openidConfig.`);
|
|
2853
2871
|
}
|
|
2854
2872
|
},
|
|
2873
|
+
onRequest: handleIssuerMetadataRequest,
|
|
2855
2874
|
hooks: {
|
|
2856
2875
|
before: [{
|
|
2857
2876
|
matcher(ctx) {
|
|
@@ -2908,6 +2927,7 @@ const oauthProvider = (options) => {
|
|
|
2908
2927
|
if (opts.scopes && opts.scopes.includes("openid")) return oidcServerMetadata(ctx, opts);
|
|
2909
2928
|
else return authServerMetadata(ctx, opts.disableJwtPlugin ? void 0 : getJwtPlugin(ctx.context)?.options, {
|
|
2910
2929
|
scopes_supported: opts.advertisedMetadata?.scopes_supported ?? opts.scopes,
|
|
2930
|
+
dynamic_client_registration_supported: opts.allowDynamicClientRegistration,
|
|
2911
2931
|
public_client_supported: opts.allowUnauthenticatedClientRegistration,
|
|
2912
2932
|
grant_types_supported: opts.grantTypes,
|
|
2913
2933
|
jwt_disabled: opts.disableJwtPlugin
|
|
@@ -4030,7 +4050,7 @@ function authServerMetadata(ctx, opts, overrides) {
|
|
|
4030
4050
|
authorization_endpoint: `${baseURL}/oauth2/authorize`,
|
|
4031
4051
|
token_endpoint: `${baseURL}/oauth2/token`,
|
|
4032
4052
|
jwks_uri: overrides?.jwt_disabled ? void 0 : opts?.jwks?.remoteUrl ?? `${baseURL}${opts?.jwks?.jwksPath ?? "/jwks"}`,
|
|
4033
|
-
registration_endpoint: `${baseURL}/oauth2/register
|
|
4053
|
+
registration_endpoint: overrides?.dynamic_client_registration_supported ? `${baseURL}/oauth2/register` : void 0,
|
|
4034
4054
|
introspection_endpoint: `${baseURL}/oauth2/introspect`,
|
|
4035
4055
|
revocation_endpoint: `${baseURL}/oauth2/revoke`,
|
|
4036
4056
|
response_types_supported: overrides?.grant_types_supported && !overrides.grant_types_supported.includes("authorization_code") ? [] : ["code"],
|
|
@@ -4057,6 +4077,7 @@ function oidcServerMetadata(ctx, opts) {
|
|
|
4057
4077
|
return {
|
|
4058
4078
|
...authServerMetadata(ctx, jwtPluginOptions, {
|
|
4059
4079
|
scopes_supported: opts.advertisedMetadata?.scopes_supported ?? opts.scopes,
|
|
4080
|
+
dynamic_client_registration_supported: opts.allowDynamicClientRegistration,
|
|
4060
4081
|
public_client_supported: opts.allowUnauthenticatedClientRegistration,
|
|
4061
4082
|
grant_types_supported: opts.grantTypes,
|
|
4062
4083
|
jwt_disabled: opts.disableJwtPlugin
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as Scope, a as OAuthClient, d as OAuthConsent, n as AuthServerMetadata, o as OIDCMetadata, p as OAuthOptions } from "./oauth-
|
|
1
|
+
import { _ as Scope, a as OAuthClient, d as OAuthConsent, n as AuthServerMetadata, o as OIDCMetadata, p as OAuthOptions } from "./oauth-D74mBkw6.mjs";
|
|
2
2
|
import * as better_call0 from "better-call";
|
|
3
3
|
import * as z from "zod";
|
|
4
4
|
import * as better_auth_plugins0 from "better-auth/plugins";
|
|
@@ -30,6 +30,11 @@ declare const oauthProvider: <O extends OAuthOptions<Scope[]>>(options: O) => {
|
|
|
30
30
|
version: string;
|
|
31
31
|
options: NoInfer<O>;
|
|
32
32
|
init: (ctx: better_auth0.AuthContext) => void;
|
|
33
|
+
onRequest: (request: Request, ctx: better_auth0.AuthContext) => Promise<{
|
|
34
|
+
response: Response;
|
|
35
|
+
} | {
|
|
36
|
+
request: Request;
|
|
37
|
+
} | void>;
|
|
33
38
|
hooks: {
|
|
34
39
|
before: {
|
|
35
40
|
matcher(ctx: better_auth0.HookEndpointContext): any;
|
|
@@ -1380,9 +1380,11 @@ interface AuthServerMetadata {
|
|
|
1380
1380
|
/**
|
|
1381
1381
|
* The URL of the dynamic client registration endpoint.
|
|
1382
1382
|
*
|
|
1383
|
+
* This field is only present when `allowDynamicClientRegistration` is enabled.
|
|
1384
|
+
*
|
|
1383
1385
|
* @default `/oauth2/register`
|
|
1384
1386
|
*/
|
|
1385
|
-
registration_endpoint
|
|
1387
|
+
registration_endpoint?: string;
|
|
1386
1388
|
/**
|
|
1387
1389
|
* Supported scopes.
|
|
1388
1390
|
*/
|
|
@@ -254,11 +254,13 @@ function basicToClientCredentials(authorization) {
|
|
|
254
254
|
if (authorization.startsWith("Basic ")) {
|
|
255
255
|
const encoded = authorization.replace("Basic ", "");
|
|
256
256
|
const decoded = new TextDecoder().decode(base64.decode(encoded));
|
|
257
|
-
|
|
257
|
+
const separatorIndex = decoded.indexOf(":");
|
|
258
|
+
if (separatorIndex === -1) throw new APIError$1("BAD_REQUEST", {
|
|
258
259
|
error_description: "invalid authorization header format",
|
|
259
260
|
error: "invalid_client"
|
|
260
261
|
});
|
|
261
|
-
const
|
|
262
|
+
const id = decoded.slice(0, separatorIndex);
|
|
263
|
+
const secret = decoded.slice(separatorIndex + 1);
|
|
262
264
|
if (!id || !secret) throw new APIError$1("BAD_REQUEST", {
|
|
263
265
|
error_description: "invalid authorization header format",
|
|
264
266
|
error: "invalid_client"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-auth/oauth-provider",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.13",
|
|
4
4
|
"description": "An oauth provider plugin for Better Auth",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -64,15 +64,15 @@
|
|
|
64
64
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
65
65
|
"listhen": "^1.9.0",
|
|
66
66
|
"tsdown": "0.21.1",
|
|
67
|
-
"@better-auth/core": "1.6.
|
|
68
|
-
"better-auth": "1.6.
|
|
67
|
+
"@better-auth/core": "1.6.13",
|
|
68
|
+
"better-auth": "1.6.13"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
|
-
"@better-auth/utils": "0.4.
|
|
71
|
+
"@better-auth/utils": "0.4.1",
|
|
72
72
|
"@better-fetch/fetch": "1.1.21",
|
|
73
73
|
"better-call": "1.3.5",
|
|
74
|
-
"@better-auth/core": "^1.6.
|
|
75
|
-
"better-auth": "^1.6.
|
|
74
|
+
"@better-auth/core": "^1.6.13",
|
|
75
|
+
"better-auth": "^1.6.13"
|
|
76
76
|
},
|
|
77
77
|
"scripts": {
|
|
78
78
|
"build": "tsdown",
|