@better-auth/core 1.4.8-beta.6 → 1.4.8
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/.turbo/turbo-build.log +10 -10
- package/dist/api/index.d.mts +1 -1
- package/dist/context/index.d.mts +1 -1
- package/dist/db/adapter/index.d.mts +1 -1
- package/dist/db/adapter/index.mjs +26 -9
- package/dist/db/index.d.mts +1 -1
- package/dist/{index-D0VJf1xh.d.mts → index-CBdZH5fV.d.mts} +53 -12
- package/dist/index.d.mts +1 -1
- package/dist/oauth2/index.d.mts +2 -2
- package/dist/oauth2/index.mjs +3 -2
- package/dist/{oauth2-D2y9ALiO.mjs → oauth2-BjWM15hm.mjs} +92 -2
- package/dist/social-providers/index.d.mts +1 -1
- package/dist/social-providers/index.mjs +11 -2
- package/package.json +1 -1
- package/src/db/adapter/factory.ts +30 -0
- package/src/db/adapter/index.ts +9 -1
- package/src/db/adapter/types.ts +10 -0
- package/src/oauth2/index.ts +5 -0
- package/src/oauth2/verify.ts +221 -0
- package/src/social-providers/cognito.ts +11 -0
- package/src/types/init-options.ts +1 -9
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @better-auth/core@1.4.8
|
|
2
|
+
> @better-auth/core@1.4.8 build /home/runner/work/better-auth/better-auth/packages/core
|
|
3
3
|
> tsdown
|
|
4
4
|
|
|
5
5
|
[34mℹ[39m tsdown [2mv0.17.2[22m powered by rolldown [2mv1.0.0-beta.53[22m
|
|
@@ -7,19 +7,19 @@
|
|
|
7
7
|
[34mℹ[39m entry: [34msrc/index.ts, src/db/index.ts, src/db/adapter/index.ts, src/async_hooks/index.ts, src/async_hooks/pure.index.ts, src/context/index.ts, src/env/index.ts, src/oauth2/index.ts, src/api/index.ts, src/social-providers/index.ts, src/utils/index.ts, src/error/index.ts[39m
|
|
8
8
|
[34mℹ[39m tsconfig: [34mtsconfig.json[39m
|
|
9
9
|
[34mℹ[39m Build start
|
|
10
|
-
[34mℹ[39m [2mdist/[22m[1msocial-providers/index.mjs[22m [2m 80.
|
|
11
|
-
[34mℹ[39m [2mdist/[22m[1mdb/adapter/index.mjs[22m [2m 38.
|
|
10
|
+
[34mℹ[39m [2mdist/[22m[1msocial-providers/index.mjs[22m [2m 80.96 kB[22m [2m│ gzip: 10.43 kB[22m
|
|
11
|
+
[34mℹ[39m [2mdist/[22m[1mdb/adapter/index.mjs[22m [2m 38.55 kB[22m [2m│ gzip: 7.86 kB[22m
|
|
12
12
|
[34mℹ[39m [2mdist/[22m[1mdb/index.mjs[22m [2m 1.66 kB[22m [2m│ gzip: 0.54 kB[22m
|
|
13
13
|
[34mℹ[39m [2mdist/[22m[1mapi/index.mjs[22m [2m 1.23 kB[22m [2m│ gzip: 0.48 kB[22m
|
|
14
14
|
[34mℹ[39m [2mdist/[22m[1masync_hooks/index.mjs[22m [2m 1.03 kB[22m [2m│ gzip: 0.54 kB[22m
|
|
15
15
|
[34mℹ[39m [2mdist/[22m[1masync_hooks/pure.index.mjs[22m [2m 0.99 kB[22m [2m│ gzip: 0.49 kB[22m
|
|
16
|
+
[34mℹ[39m [2mdist/[22m[1moauth2/index.mjs[22m [2m 0.75 kB[22m [2m│ gzip: 0.28 kB[22m
|
|
16
17
|
[34mℹ[39m [2mdist/[22m[1mcontext/index.mjs[22m [2m 0.70 kB[22m [2m│ gzip: 0.24 kB[22m
|
|
17
|
-
[34mℹ[39m [2mdist/[22m[1moauth2/index.mjs[22m [2m 0.61 kB[22m [2m│ gzip: 0.24 kB[22m
|
|
18
18
|
[34mℹ[39m [2mdist/[22m[1menv/index.mjs[22m [2m 0.44 kB[22m [2m│ gzip: 0.25 kB[22m
|
|
19
19
|
[34mℹ[39m [2mdist/[22m[1mutils/index.mjs[22m [2m 0.24 kB[22m [2m│ gzip: 0.17 kB[22m
|
|
20
20
|
[34mℹ[39m [2mdist/[22m[1merror/index.mjs[22m [2m 0.19 kB[22m [2m│ gzip: 0.14 kB[22m
|
|
21
21
|
[34mℹ[39m [2mdist/[22m[1mindex.mjs[22m [2m 0.01 kB[22m [2m│ gzip: 0.03 kB[22m
|
|
22
|
-
[34mℹ[39m [2mdist/[22moauth2-
|
|
22
|
+
[34mℹ[39m [2mdist/[22moauth2-BjWM15hm.mjs [2m 12.82 kB[22m [2m│ gzip: 3.16 kB[22m
|
|
23
23
|
[34mℹ[39m [2mdist/[22menv-DbssmzoK.mjs [2m 7.67 kB[22m [2m│ gzip: 2.54 kB[22m
|
|
24
24
|
[34mℹ[39m [2mdist/[22mget-tables-CMc_Emww.mjs [2m 6.76 kB[22m [2m│ gzip: 1.30 kB[22m
|
|
25
25
|
[34mℹ[39m [2mdist/[22mcontext-DblZrIwO.mjs [2m 3.89 kB[22m [2m│ gzip: 1.00 kB[22m
|
|
@@ -30,14 +30,14 @@
|
|
|
30
30
|
[34mℹ[39m [2mdist/[22m[32m[1merror/index.d.mts[22m[39m [2m 1.84 kB[22m [2m│ gzip: 0.72 kB[22m
|
|
31
31
|
[34mℹ[39m [2mdist/[22m[32m[1mdb/adapter/index.d.mts[22m[39m [2m 1.34 kB[22m [2m│ gzip: 0.43 kB[22m
|
|
32
32
|
[34mℹ[39m [2mdist/[22m[32m[1mutils/index.d.mts[22m[39m [2m 1.19 kB[22m [2m│ gzip: 0.55 kB[22m
|
|
33
|
-
[34mℹ[39m [2mdist/[22m[32m[1mindex.d.mts[22m[39m [2m 0.92 kB[22m [2m│ gzip: 0.
|
|
33
|
+
[34mℹ[39m [2mdist/[22m[32m[1mindex.d.mts[22m[39m [2m 0.92 kB[22m [2m│ gzip: 0.36 kB[22m
|
|
34
|
+
[34mℹ[39m [2mdist/[22m[32m[1moauth2/index.d.mts[22m[39m [2m 0.88 kB[22m [2m│ gzip: 0.32 kB[22m
|
|
34
35
|
[34mℹ[39m [2mdist/[22m[32m[1mdb/index.d.mts[22m[39m [2m 0.81 kB[22m [2m│ gzip: 0.34 kB[22m
|
|
35
|
-
[34mℹ[39m [2mdist/[22m[32m[1moauth2/index.d.mts[22m[39m [2m 0.76 kB[22m [2m│ gzip: 0.28 kB[22m
|
|
36
36
|
[34mℹ[39m [2mdist/[22m[32m[1menv/index.d.mts[22m[39m [2m 0.59 kB[22m [2m│ gzip: 0.30 kB[22m
|
|
37
37
|
[34mℹ[39m [2mdist/[22m[32m[1mapi/index.d.mts[22m[39m [2m 0.26 kB[22m [2m│ gzip: 0.14 kB[22m
|
|
38
38
|
[34mℹ[39m [2mdist/[22m[32m[1masync_hooks/index.d.mts[22m[39m [2m 0.24 kB[22m [2m│ gzip: 0.16 kB[22m
|
|
39
39
|
[34mℹ[39m [2mdist/[22m[32m[1masync_hooks/pure.index.d.mts[22m[39m [2m 0.22 kB[22m [2m│ gzip: 0.16 kB[22m
|
|
40
|
-
[34mℹ[39m [2mdist/[22m[32mindex-
|
|
40
|
+
[34mℹ[39m [2mdist/[22m[32mindex-CBdZH5fV.d.mts[39m [2m221.21 kB[22m [2m│ gzip: 35.26 kB[22m
|
|
41
41
|
[34mℹ[39m [2mdist/[22m[32mindex-BRBu0-5h.d.mts[39m [2m 3.31 kB[22m [2m│ gzip: 1.11 kB[22m
|
|
42
|
-
[34mℹ[39m 32 files, total:
|
|
43
|
-
[32m✔[39m Build complete in [
|
|
42
|
+
[34mℹ[39m 32 files, total: 400.50 kB
|
|
43
|
+
[32m✔[39m Build complete in [32m4838ms[39m
|
package/dist/api/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as optionsMiddleware, i as createAuthMiddleware, n as AuthMiddleware, r as createAuthEndpoint, t as AuthEndpoint } from "../index-
|
|
1
|
+
import { a as optionsMiddleware, i as createAuthMiddleware, n as AuthMiddleware, r as createAuthEndpoint, t as AuthEndpoint } from "../index-CBdZH5fV.mjs";
|
|
2
2
|
export { AuthEndpoint, AuthMiddleware, createAuthEndpoint, createAuthMiddleware, optionsMiddleware };
|
package/dist/context/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Yn as DBAdapter, er as DBTransactionAdapter, f as AuthContext } from "../index-CBdZH5fV.mjs";
|
|
2
2
|
import { AsyncLocalStorage } from "@better-auth/core/async_hooks";
|
|
3
3
|
import { EndpointContext, InputContext } from "better-call";
|
|
4
4
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $n as
|
|
1
|
+
import { $n as DBAdapterSchemaCreation, Cr as initGetFieldName, Er as initGetDefaultFieldName, Jn as CustomAdapter, Qn as DBAdapterInstance, Sr as initGetIdField, Tr as initGetDefaultModelName, Xn as DBAdapterDebugLogOption, Yn as DBAdapter, Zn as DBAdapterFactoryConfig, ar as withApplyDefault, cr as createAdapterFactory, dr as AdapterFactoryCustomizeAdapterCreator, er as DBTransactionAdapter, fr as AdapterFactoryOptions, hr as CreateCustomAdapter, ir as deepmerge, lr as AdapterConfig, mr as CreateAdapterOptions, nr as JoinOption, or as AdapterFactory, pr as AdapterTestDebugLogs, qn as CleanedWhere, rr as Where, sr as createAdapter, tr as JoinConfig, ur as AdapterFactoryConfig, wr as initGetFieldAttributes, xr as initGetModelName } from "../../index-CBdZH5fV.mjs";
|
|
2
2
|
export { AdapterConfig, AdapterFactory, AdapterFactoryConfig, AdapterFactoryCustomizeAdapterCreator, AdapterFactoryOptions, AdapterTestDebugLogs, CleanedWhere, CreateAdapterOptions, CreateCustomAdapter, CustomAdapter, DBAdapter, DBAdapterDebugLogOption, DBAdapterFactoryConfig, DBAdapterInstance, DBAdapterSchemaCreation, DBTransactionAdapter, JoinConfig, JoinOption, Where, createAdapter, createAdapterFactory, deepmerge, initGetDefaultFieldName, initGetDefaultModelName, initGetFieldAttributes, initGetFieldName, initGetIdField, initGetModelName, withApplyDefault };
|
|
@@ -443,7 +443,7 @@ const createAdapterFactory = ({ adapter: customAdapter, config: cfg }) => (optio
|
|
|
443
443
|
}
|
|
444
444
|
return transformedData;
|
|
445
445
|
};
|
|
446
|
-
const transformWhereClause = ({ model, where }) => {
|
|
446
|
+
const transformWhereClause = ({ model, where, action }) => {
|
|
447
447
|
if (!where) return void 0;
|
|
448
448
|
const newMappedKeys = config.mapKeysTransformInput ?? {};
|
|
449
449
|
return where.map((w) => {
|
|
@@ -477,6 +477,15 @@ const createAdapterFactory = ({ adapter: customAdapter, config: cfg }) => (optio
|
|
|
477
477
|
} catch (error) {
|
|
478
478
|
throw new Error(`Failed to stringify JSON value for field ${fieldName}`, { cause: error });
|
|
479
479
|
}
|
|
480
|
+
if (config.customTransformInput) newValue = config.customTransformInput({
|
|
481
|
+
data: newValue,
|
|
482
|
+
fieldAttributes: fieldAttr,
|
|
483
|
+
field: fieldName,
|
|
484
|
+
model: getModelName(model),
|
|
485
|
+
schema,
|
|
486
|
+
options,
|
|
487
|
+
action
|
|
488
|
+
});
|
|
480
489
|
return {
|
|
481
490
|
operator,
|
|
482
491
|
connector,
|
|
@@ -566,7 +575,8 @@ const createAdapterFactory = ({ adapter: customAdapter, config: cfg }) => (optio
|
|
|
566
575
|
value,
|
|
567
576
|
operator: "eq",
|
|
568
577
|
connector: "AND"
|
|
569
|
-
}]
|
|
578
|
+
}],
|
|
579
|
+
action: "findOne"
|
|
570
580
|
});
|
|
571
581
|
try {
|
|
572
582
|
if (joinConfig.relation === "one-to-one") result = await adapterInstance.findOne({
|
|
@@ -658,7 +668,8 @@ const createAdapterFactory = ({ adapter: customAdapter, config: cfg }) => (optio
|
|
|
658
668
|
const model = getModelName(unsafeModel);
|
|
659
669
|
const where = transformWhereClause({
|
|
660
670
|
model: unsafeModel,
|
|
661
|
-
where: unsafeWhere
|
|
671
|
+
where: unsafeWhere,
|
|
672
|
+
action: "update"
|
|
662
673
|
});
|
|
663
674
|
debugLog({ method: "update" }, `${formatTransactionId(thisTransactionId)} ${formatStep(1, 4)}`, `${formatMethod("update")} ${formatAction("Unsafe Input")}:`, {
|
|
664
675
|
model,
|
|
@@ -693,7 +704,8 @@ const createAdapterFactory = ({ adapter: customAdapter, config: cfg }) => (optio
|
|
|
693
704
|
const model = getModelName(unsafeModel);
|
|
694
705
|
const where = transformWhereClause({
|
|
695
706
|
model: unsafeModel,
|
|
696
|
-
where: unsafeWhere
|
|
707
|
+
where: unsafeWhere,
|
|
708
|
+
action: "updateMany"
|
|
697
709
|
});
|
|
698
710
|
unsafeModel = getDefaultModelName(unsafeModel);
|
|
699
711
|
debugLog({ method: "updateMany" }, `${formatTransactionId(thisTransactionId)} ${formatStep(1, 4)}`, `${formatMethod("updateMany")} ${formatAction("Unsafe Input")}:`, {
|
|
@@ -727,7 +739,8 @@ const createAdapterFactory = ({ adapter: customAdapter, config: cfg }) => (optio
|
|
|
727
739
|
const model = getModelName(unsafeModel);
|
|
728
740
|
const where = transformWhereClause({
|
|
729
741
|
model: unsafeModel,
|
|
730
|
-
where: unsafeWhere
|
|
742
|
+
where: unsafeWhere,
|
|
743
|
+
action: "findOne"
|
|
731
744
|
});
|
|
732
745
|
unsafeModel = getDefaultModelName(unsafeModel);
|
|
733
746
|
let join;
|
|
@@ -771,7 +784,8 @@ const createAdapterFactory = ({ adapter: customAdapter, config: cfg }) => (optio
|
|
|
771
784
|
const model = getModelName(unsafeModel);
|
|
772
785
|
const where = transformWhereClause({
|
|
773
786
|
model: unsafeModel,
|
|
774
|
-
where: unsafeWhere
|
|
787
|
+
where: unsafeWhere,
|
|
788
|
+
action: "findMany"
|
|
775
789
|
});
|
|
776
790
|
unsafeModel = getDefaultModelName(unsafeModel);
|
|
777
791
|
let join;
|
|
@@ -817,7 +831,8 @@ const createAdapterFactory = ({ adapter: customAdapter, config: cfg }) => (optio
|
|
|
817
831
|
const model = getModelName(unsafeModel);
|
|
818
832
|
const where = transformWhereClause({
|
|
819
833
|
model: unsafeModel,
|
|
820
|
-
where: unsafeWhere
|
|
834
|
+
where: unsafeWhere,
|
|
835
|
+
action: "delete"
|
|
821
836
|
});
|
|
822
837
|
unsafeModel = getDefaultModelName(unsafeModel);
|
|
823
838
|
debugLog({ method: "delete" }, `${formatTransactionId(thisTransactionId)} ${formatStep(1, 2)}`, `${formatMethod("delete")}:`, {
|
|
@@ -836,7 +851,8 @@ const createAdapterFactory = ({ adapter: customAdapter, config: cfg }) => (optio
|
|
|
836
851
|
const model = getModelName(unsafeModel);
|
|
837
852
|
const where = transformWhereClause({
|
|
838
853
|
model: unsafeModel,
|
|
839
|
-
where: unsafeWhere
|
|
854
|
+
where: unsafeWhere,
|
|
855
|
+
action: "deleteMany"
|
|
840
856
|
});
|
|
841
857
|
unsafeModel = getDefaultModelName(unsafeModel);
|
|
842
858
|
debugLog({ method: "deleteMany" }, `${formatTransactionId(thisTransactionId)} ${formatStep(1, 2)}`, `${formatMethod("deleteMany")} ${formatAction("DeleteMany")}:`, {
|
|
@@ -859,7 +875,8 @@ const createAdapterFactory = ({ adapter: customAdapter, config: cfg }) => (optio
|
|
|
859
875
|
const model = getModelName(unsafeModel);
|
|
860
876
|
const where = transformWhereClause({
|
|
861
877
|
model: unsafeModel,
|
|
862
|
-
where: unsafeWhere
|
|
878
|
+
where: unsafeWhere,
|
|
879
|
+
action: "count"
|
|
863
880
|
});
|
|
864
881
|
unsafeModel = getDefaultModelName(unsafeModel);
|
|
865
882
|
debugLog({ method: "count" }, `${formatTransactionId(thisTransactionId)} ${formatStep(1, 2)}`, `${formatMethod("count")}:`, {
|
package/dist/db/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Ar as
|
|
1
|
+
import { Ar as userSchema, Br as BaseModelNames, Dr as Verification, Fr as rateLimitSchema, Gr as DBPrimitive, Hr as DBFieldAttribute, Ir as Account, Kr as ModelNames, Lr as accountSchema, Mr as Session, Nr as sessionSchema, Or as verificationSchema, Pr as RateLimit, Rr as BetterAuthPluginDBSchema, Ur as DBFieldAttributeConfig, Vr as BetterAuthDBSchema, Wr as DBFieldType, jr as coreSchema, kr as User, qr as SecondaryStorage, zr as getAuthTables } from "../index-CBdZH5fV.mjs";
|
|
2
2
|
export { Account, BaseModelNames, BetterAuthDBSchema, BetterAuthPluginDBSchema, DBFieldAttribute, DBFieldAttributeConfig, DBFieldType, DBPrimitive, ModelNames, RateLimit, SecondaryStorage, Session, User, Verification, accountSchema, coreSchema, getAuthTables, rateLimitSchema, sessionSchema, userSchema, verificationSchema };
|
|
@@ -2,6 +2,7 @@ import { i as Logger, o as createLogger } from "./index-BRBu0-5h.mjs";
|
|
|
2
2
|
import * as z from "zod";
|
|
3
3
|
import { BetterFetch, BetterFetchOption, BetterFetchPlugin } from "@better-fetch/fetch";
|
|
4
4
|
import * as jose0 from "jose";
|
|
5
|
+
import { JSONWebKeySet, JWTPayload, JWTVerifyOptions } from "jose";
|
|
5
6
|
import * as better_call0 from "better-call";
|
|
6
7
|
import { CookieOptions, Endpoint, EndpointContext, EndpointOptions, InputContext, Middleware, StrictEndpoint } from "better-call";
|
|
7
8
|
import { StandardSchemaV1, StandardSchemaV1 as StandardSchemaV1$1 } from "@standard-schema/spec";
|
|
@@ -451,10 +452,12 @@ type AdapterFactoryCustomizeAdapterCreator = (config: {
|
|
|
451
452
|
transformOutput: (data: Record<string, unknown>, defaultModelName: string, select?: string[] | undefined, joinConfig?: JoinConfig | undefined) => Promise<Record<string, unknown>>;
|
|
452
453
|
transformWhereClause: <W extends Where[] | undefined>({
|
|
453
454
|
model,
|
|
454
|
-
where
|
|
455
|
+
where,
|
|
456
|
+
action
|
|
455
457
|
}: {
|
|
456
458
|
where: W;
|
|
457
459
|
model: string;
|
|
460
|
+
action: "create" | "update" | "findOne" | "findMany" | "updateMany" | "delete" | "deleteMany" | "count";
|
|
458
461
|
}) => W extends undefined ? undefined : CleanedWhere$1[];
|
|
459
462
|
}) => CustomAdapter$1;
|
|
460
463
|
/**
|
|
@@ -700,7 +703,7 @@ interface DBAdapterFactoryConfig<Options extends BetterAuthOptions = BetterAuthO
|
|
|
700
703
|
/**
|
|
701
704
|
* The action which was called from the adapter.
|
|
702
705
|
*/
|
|
703
|
-
action: "create" | "update" | "findOne" | "findMany";
|
|
706
|
+
action: "create" | "update" | "findOne" | "findMany" | "updateMany" | "delete" | "deleteMany" | "count";
|
|
704
707
|
/**
|
|
705
708
|
* The model name.
|
|
706
709
|
*/
|
|
@@ -1357,6 +1360,52 @@ declare function validateAuthorizationCode({
|
|
|
1357
1360
|
}): Promise<OAuth2Tokens>;
|
|
1358
1361
|
declare function validateToken(token: string, jwksEndpoint: string): Promise<jose0.JWTVerifyResult<jose0.JWTPayload>>;
|
|
1359
1362
|
//#endregion
|
|
1363
|
+
//#region src/oauth2/verify.d.ts
|
|
1364
|
+
interface VerifyAccessTokenRemote {
|
|
1365
|
+
/** Full url of the introspect endpoint. Should end with `/oauth2/introspect` */
|
|
1366
|
+
introspectUrl: string;
|
|
1367
|
+
/** Client Secret */
|
|
1368
|
+
clientId: string;
|
|
1369
|
+
/** Client Secret */
|
|
1370
|
+
clientSecret: string;
|
|
1371
|
+
/**
|
|
1372
|
+
* Forces remote verification of a token.
|
|
1373
|
+
* This ensures attached session (if applicable)
|
|
1374
|
+
* is also still active.
|
|
1375
|
+
*/
|
|
1376
|
+
force?: boolean;
|
|
1377
|
+
}
|
|
1378
|
+
/**
|
|
1379
|
+
* Performs local verification of an access token for your APIs.
|
|
1380
|
+
*
|
|
1381
|
+
* Can also be configured for remote verification.
|
|
1382
|
+
*/
|
|
1383
|
+
declare function verifyJwsAccessToken(token: string, opts: {
|
|
1384
|
+
/** Jwks url or promise of a Jwks */
|
|
1385
|
+
jwksFetch: string | (() => Promise<JSONWebKeySet | undefined>);
|
|
1386
|
+
/** Verify options */
|
|
1387
|
+
verifyOptions: JWTVerifyOptions & Required<Pick<JWTVerifyOptions, "audience" | "issuer">>;
|
|
1388
|
+
}): Promise<JWTPayload>;
|
|
1389
|
+
declare function getJwks(token: string, opts: {
|
|
1390
|
+
/** Jwks url or promise of a Jwks */
|
|
1391
|
+
jwksFetch: string | (() => Promise<JSONWebKeySet | undefined>);
|
|
1392
|
+
}): Promise<JSONWebKeySet>;
|
|
1393
|
+
/**
|
|
1394
|
+
* Performs local verification of an access token for your API.
|
|
1395
|
+
*
|
|
1396
|
+
* Can also be configured for remote verification.
|
|
1397
|
+
*/
|
|
1398
|
+
declare function verifyAccessToken(token: string, opts: {
|
|
1399
|
+
/** Verify options */
|
|
1400
|
+
verifyOptions: JWTVerifyOptions & Required<Pick<JWTVerifyOptions, "audience" | "issuer">>;
|
|
1401
|
+
/** Scopes to additionally verify. Token must include all but not exact. */
|
|
1402
|
+
scopes?: string[];
|
|
1403
|
+
/** Required to verify access token locally */
|
|
1404
|
+
jwksUrl?: string;
|
|
1405
|
+
/** If provided, can verify a token remotely */
|
|
1406
|
+
remoteVerify?: VerifyAccessTokenRemote;
|
|
1407
|
+
}): Promise<JWTPayload>;
|
|
1408
|
+
//#endregion
|
|
1360
1409
|
//#region src/types/cookie.d.ts
|
|
1361
1410
|
type BetterAuthCookies = {
|
|
1362
1411
|
sessionToken: {
|
|
@@ -7139,16 +7188,8 @@ type BetterAuthOptions = {
|
|
|
7139
7188
|
} | undefined;
|
|
7140
7189
|
/**
|
|
7141
7190
|
* List of trusted origins.
|
|
7142
|
-
*
|
|
7143
|
-
* @param request - The request object.
|
|
7144
|
-
* It'll be undefined if no request was
|
|
7145
|
-
* made. Like during a create context call
|
|
7146
|
-
* or `auth.api` call.
|
|
7147
|
-
*
|
|
7148
|
-
* Trusted origins will be dynamically
|
|
7149
|
-
* calculated based on the request.
|
|
7150
7191
|
*/
|
|
7151
|
-
trustedOrigins?: (string[] | ((request
|
|
7192
|
+
trustedOrigins?: (string[] | ((request: Request) => Awaitable<string[]>)) | undefined;
|
|
7152
7193
|
/**
|
|
7153
7194
|
* Rate limiting configuration
|
|
7154
7195
|
*/
|
|
@@ -7771,4 +7812,4 @@ declare function createAuthEndpoint<Path extends string, Options extends Endpoin
|
|
|
7771
7812
|
type AuthEndpoint<Path extends string, Opts extends EndpointOptions, R> = ReturnType<typeof createAuthEndpoint<Path, Opts, R>>;
|
|
7772
7813
|
type AuthMiddleware = ReturnType<typeof createAuthMiddleware>;
|
|
7773
7814
|
//#endregion
|
|
7774
|
-
export { AccountStatus as $,
|
|
7815
|
+
export { AccountStatus as $, DBAdapterSchemaCreation as $n, GoogleProfile as $t, PolarOptions as A, getJwks as An, userSchema as Ar, linear as At, LineIdTokenPayload as B, createAuthorizationURL as Bn, BaseModelNames as Br, TwitchOptions as Bt, SocialProviderListEnum as C, atlassian as Cn, initGetFieldName as Cr, gitlab as Ct, VercelOptions as D, apple as Dn, Verification as Dr, LinearOptions as Dt, socialProviders as E, AppleProfile as En, initGetDefaultFieldName as Er, linkedin as Et, PayPalTokenResponse as F, validateToken as Fn, rateLimitSchema as Fr, DropboxProfile as Ft, NaverProfile as G, OAuthProvider as Gn, DBPrimitive as Gr, spotify as Gt, LineUserInfo as H, createClientCredentialsTokenRequest as Hn, DBFieldAttribute as Hr, twitch as Ht, paypal as I, generateCodeChallenge as In, Account as Ir, dropbox as It, KakaoProfile as J, CustomAdapter as Jn, slack as Jt, naver as K, ProviderOptions as Kn, ModelNames as Kr, SlackOptions as Kt, PaybinOptions as L, getOAuth2Tokens as Ln, accountSchema as Lr, TwitterOption as Lt, polar as M, verifyJwsAccessToken as Mn, Session as Mr, KickProfile as Mt, PayPalOptions as N, createAuthorizationCodeRequest as Nn, sessionSchema as Nr, kick as Nt, VercelProfile as O, getApplePublicKey as On, verificationSchema as Or, LinearProfile as Ot, PayPalProfile as P, validateAuthorizationCode as Pn, RateLimit as Pr, DropboxOptions as Pt, notion as Q, DBAdapterInstance as Qn, GoogleOptions as Qt, PaybinProfile as R, createRefreshAccessTokenRequest as Rn, BetterAuthPluginDBSchema as Rr, TwitterProfile as Rt, SocialProviderList as S, AtlassianProfile as Sn, initGetIdField as Sr, GitlabProfile as St, socialProviderList as T, AppleOptions as Tn, initGetDefaultModelName as Tr, LinkedInProfile as Tt, line as U, OAuth2Tokens as Un, DBFieldAttributeConfig as Ur, SpotifyOptions as Ut, LineOptions as V, clientCredentialsToken as Vn, BetterAuthDBSchema as Vr, TwitchProfile as Vt, NaverOptions as W, OAuth2UserInfo as Wn, DBFieldType as Wr, SpotifyProfile as Wt, NotionOptions as X, DBAdapterDebugLogOption as Xn, HuggingFaceProfile as Xt, kakao as Y, DBAdapter as Yn, HuggingFaceOptions as Yt, NotionProfile as Z, DBAdapterFactoryConfig as Zn, huggingface as Zt, BetterAuthRateLimitOptions as _, CognitoOptions as _n, LiteralString as _r, reddit as _t, optionsMiddleware as a, GithubOptions as an, withApplyDefault as ar, zoom as at, HookEndpointContext as b, getCognitoPublicKey as bn, Primitive as br, tiktok as bt, BetterAuthClientPlugin as c, FigmaOptions as cn, createAdapterFactory as cr, vk as ct, ClientStore as d, FacebookOptions as dn, AdapterFactoryCustomizeAdapterCreator as dr, salesforce as dt, getGooglePublicKey as en, DBTransactionAdapter as er, LoginType as et, AuthContext as f, FacebookProfile as fn, AdapterFactoryOptions as fr, RobloxOptions as ft, BetterAuthOptions as g, discord as gn, Awaitable as gr, RedditProfile as gt, BetterAuthAdvancedOptions as h, DiscordProfile as hn, CreateCustomAdapter as hr, RedditOptions as ht, createAuthMiddleware as i, microsoft as in, deepmerge as ir, ZoomProfile as it, PolarProfile as j, verifyAccessToken as jn, coreSchema as jr, KickOptions as jt, vercel as k, BetterAuthCookies as kn, User as kr, LinearUser as kt, ClientAtomListener as l, FigmaProfile as ln, AdapterConfig as lr, SalesforceOptions as lt, InternalAdapter as m, DiscordOptions as mn, CreateAdapterOptions as mr, roblox as mt, AuthMiddleware as n, MicrosoftEntraIDProfile as nn, JoinOption as nr, PronounOption as nt, StandardSchemaV1$1 as o, GithubProfile as on, AdapterFactory as or, VkOption as ot, GenericEndpointContext as p, facebook as pn, AdapterTestDebugLogs as pr, RobloxProfile as pt, KakaoOptions as q, CleanedWhere as qn, SecondaryStorage as qr, SlackProfile as qt, createAuthEndpoint as r, MicrosoftOptions as rn, Where as rr, ZoomOptions as rt, BetterAuthClientOptions as s, github as sn, createAdapter as sr, VkProfile as st, AuthEndpoint as t, google as tn, JoinConfig as tr, PhoneNumber as tt, ClientFetchOption as u, figma as un, AdapterFactoryConfig as ur, SalesforceProfile as ut, GenerateIdFn as v, CognitoProfile as vn, LiteralUnion as vr, TiktokOptions as vt, SocialProviders as w, AppleNonConformUser as wn, initGetFieldAttributes as wr, LinkedInOptions as wt, SocialProvider as x, AtlassianOptions as xn, initGetModelName as xr, GitlabOptions as xt, BetterAuthPlugin as y, cognito as yn, Prettify as yr, TiktokProfile as yt, paybin as z, refreshAccessToken as zn, getAuthTables as zr, twitter as zt };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as BetterAuthRateLimitOptions, _r as
|
|
1
|
+
import { _ as BetterAuthRateLimitOptions, _r as LiteralString, b as HookEndpointContext, br as Primitive, c as BetterAuthClientPlugin, d as ClientStore, f as AuthContext, g as BetterAuthOptions, gr as Awaitable, h as BetterAuthAdvancedOptions, kn as BetterAuthCookies, l as ClientAtomListener, m as InternalAdapter, o as StandardSchemaV1, p as GenericEndpointContext, s as BetterAuthClientOptions, u as ClientFetchOption, v as GenerateIdFn, vr as LiteralUnion, y as BetterAuthPlugin, yr as Prettify } from "./index-CBdZH5fV.mjs";
|
|
2
2
|
export { AuthContext, Awaitable, BetterAuthAdvancedOptions, BetterAuthClientOptions, BetterAuthClientPlugin, BetterAuthCookies, BetterAuthOptions, BetterAuthPlugin, BetterAuthRateLimitOptions, ClientAtomListener, ClientFetchOption, ClientStore, GenerateIdFn, GenericEndpointContext, HookEndpointContext, InternalAdapter, LiteralString, LiteralUnion, Prettify, Primitive, StandardSchemaV1 };
|
package/dist/oauth2/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { An as
|
|
2
|
-
export { OAuth2Tokens, OAuth2UserInfo, OAuthProvider, ProviderOptions, clientCredentialsToken, createAuthorizationCodeRequest, createAuthorizationURL, createClientCredentialsTokenRequest, createRefreshAccessTokenRequest, generateCodeChallenge, getOAuth2Tokens, refreshAccessToken, validateAuthorizationCode, validateToken };
|
|
1
|
+
import { An as getJwks, Bn as createAuthorizationURL, Fn as validateToken, Gn as OAuthProvider, Hn as createClientCredentialsTokenRequest, In as generateCodeChallenge, Kn as ProviderOptions, Ln as getOAuth2Tokens, Mn as verifyJwsAccessToken, Nn as createAuthorizationCodeRequest, Pn as validateAuthorizationCode, Rn as createRefreshAccessTokenRequest, Un as OAuth2Tokens, Vn as clientCredentialsToken, Wn as OAuth2UserInfo, jn as verifyAccessToken, zn as refreshAccessToken } from "../index-CBdZH5fV.mjs";
|
|
2
|
+
export { OAuth2Tokens, OAuth2UserInfo, OAuthProvider, ProviderOptions, clientCredentialsToken, createAuthorizationCodeRequest, createAuthorizationURL, createClientCredentialsTokenRequest, createRefreshAccessTokenRequest, generateCodeChallenge, getJwks, getOAuth2Tokens, refreshAccessToken, validateAuthorizationCode, validateToken, verifyAccessToken, verifyJwsAccessToken };
|
package/dist/oauth2/index.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "../env-DbssmzoK.mjs";
|
|
2
|
+
import { a as validateAuthorizationCode, c as refreshAccessToken, d as getOAuth2Tokens, f as clientCredentialsToken, i as createAuthorizationCodeRequest, l as createAuthorizationURL, n as verifyAccessToken, o as validateToken, p as createClientCredentialsTokenRequest, r as verifyJwsAccessToken, s as createRefreshAccessTokenRequest, t as getJwks, u as generateCodeChallenge } from "../oauth2-BjWM15hm.mjs";
|
|
2
3
|
|
|
3
|
-
export { clientCredentialsToken, createAuthorizationCodeRequest, createAuthorizationURL, createClientCredentialsTokenRequest, createRefreshAccessTokenRequest, generateCodeChallenge, getOAuth2Tokens, refreshAccessToken, validateAuthorizationCode, validateToken };
|
|
4
|
+
export { clientCredentialsToken, createAuthorizationCodeRequest, createAuthorizationURL, createClientCredentialsTokenRequest, createRefreshAccessTokenRequest, generateCodeChallenge, getJwks, getOAuth2Tokens, refreshAccessToken, validateAuthorizationCode, validateToken, verifyAccessToken, verifyJwsAccessToken };
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { i as logger } from "./env-DbssmzoK.mjs";
|
|
1
2
|
import { base64, base64Url } from "@better-auth/utils/base64";
|
|
2
3
|
import { betterFetch } from "@better-fetch/fetch";
|
|
3
|
-
import { jwtVerify } from "jose";
|
|
4
|
+
import { UnsecuredJWT, createLocalJWKSet, decodeProtectedHeader, jwtVerify } from "jose";
|
|
5
|
+
import { APIError } from "better-call";
|
|
4
6
|
|
|
5
7
|
//#region src/oauth2/client-credentials-token.ts
|
|
6
8
|
function createClientCredentialsTokenRequest({ options, scope, authentication, resource }) {
|
|
@@ -233,4 +235,92 @@ async function validateToken(token, jwksEndpoint) {
|
|
|
233
235
|
}
|
|
234
236
|
|
|
235
237
|
//#endregion
|
|
236
|
-
|
|
238
|
+
//#region src/oauth2/verify.ts
|
|
239
|
+
/** Last fetched jwks used locally in getJwks @internal */
|
|
240
|
+
let jwks;
|
|
241
|
+
/**
|
|
242
|
+
* Performs local verification of an access token for your APIs.
|
|
243
|
+
*
|
|
244
|
+
* Can also be configured for remote verification.
|
|
245
|
+
*/
|
|
246
|
+
async function verifyJwsAccessToken(token, opts) {
|
|
247
|
+
try {
|
|
248
|
+
const jwt = await jwtVerify(token, createLocalJWKSet(await getJwks(token, opts)), opts.verifyOptions);
|
|
249
|
+
if (jwt.payload.azp) jwt.payload.client_id = jwt.payload.azp;
|
|
250
|
+
return jwt.payload;
|
|
251
|
+
} catch (error) {
|
|
252
|
+
if (error instanceof Error) throw error;
|
|
253
|
+
throw new Error(error);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
async function getJwks(token, opts) {
|
|
257
|
+
let jwtHeaders;
|
|
258
|
+
try {
|
|
259
|
+
jwtHeaders = decodeProtectedHeader(token);
|
|
260
|
+
} catch (error) {
|
|
261
|
+
if (error instanceof Error) throw error;
|
|
262
|
+
throw new Error(error);
|
|
263
|
+
}
|
|
264
|
+
if (!jwtHeaders.kid) throw new Error("Missing jwt kid");
|
|
265
|
+
if (!jwks || !jwks.keys.find((jwk) => jwk.kid === jwtHeaders.kid)) {
|
|
266
|
+
jwks = typeof opts.jwksFetch === "string" ? await betterFetch(opts.jwksFetch, { headers: { Accept: "application/json" } }).then(async (res) => {
|
|
267
|
+
if (res.error) throw new Error(`Jwks failed: ${res.error.message ?? res.error.statusText}`);
|
|
268
|
+
return res.data;
|
|
269
|
+
}) : await opts.jwksFetch();
|
|
270
|
+
if (!jwks) throw new Error("No jwks found");
|
|
271
|
+
}
|
|
272
|
+
return jwks;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Performs local verification of an access token for your API.
|
|
276
|
+
*
|
|
277
|
+
* Can also be configured for remote verification.
|
|
278
|
+
*/
|
|
279
|
+
async function verifyAccessToken(token, opts) {
|
|
280
|
+
let payload;
|
|
281
|
+
if (opts.jwksUrl && !opts?.remoteVerify?.force) try {
|
|
282
|
+
payload = await verifyJwsAccessToken(token, {
|
|
283
|
+
jwksFetch: opts.jwksUrl,
|
|
284
|
+
verifyOptions: opts.verifyOptions
|
|
285
|
+
});
|
|
286
|
+
} catch (error) {
|
|
287
|
+
if (error instanceof Error) if (error.name === "TypeError" || error.name === "JWSInvalid") {} else if (error.name === "JWTExpired") throw new APIError("UNAUTHORIZED", { message: "token expired" });
|
|
288
|
+
else if (error.name === "JWTInvalid") throw new APIError("UNAUTHORIZED", { message: "token invalid" });
|
|
289
|
+
else throw error;
|
|
290
|
+
else throw new Error(error);
|
|
291
|
+
}
|
|
292
|
+
if (opts?.remoteVerify) {
|
|
293
|
+
const { data: introspect, error: introspectError } = await betterFetch(opts.remoteVerify.introspectUrl, {
|
|
294
|
+
method: "POST",
|
|
295
|
+
headers: {
|
|
296
|
+
Accept: "application/json",
|
|
297
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
298
|
+
},
|
|
299
|
+
body: new URLSearchParams({
|
|
300
|
+
client_id: opts.remoteVerify.clientId,
|
|
301
|
+
client_secret: opts.remoteVerify.clientSecret,
|
|
302
|
+
token,
|
|
303
|
+
token_type_hint: "access_token"
|
|
304
|
+
}).toString()
|
|
305
|
+
});
|
|
306
|
+
if (introspectError) logger.error(`Introspection failed: ${introspectError.message ?? introspectError.statusText}`);
|
|
307
|
+
if (!introspect) throw new APIError("INTERNAL_SERVER_ERROR", { message: "introspection failed" });
|
|
308
|
+
if (!introspect.active) throw new APIError("UNAUTHORIZED", { message: "token inactive" });
|
|
309
|
+
try {
|
|
310
|
+
const unsecuredJwt = new UnsecuredJWT(introspect).encode();
|
|
311
|
+
const { audience: _audience, ...verifyOptions } = opts.verifyOptions;
|
|
312
|
+
payload = (introspect.aud ? UnsecuredJWT.decode(unsecuredJwt, opts.verifyOptions) : UnsecuredJWT.decode(unsecuredJwt, verifyOptions)).payload;
|
|
313
|
+
} catch (error) {
|
|
314
|
+
throw new Error(error);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
if (!payload) throw new APIError("UNAUTHORIZED", { message: `no token payload` });
|
|
318
|
+
if (opts.scopes) {
|
|
319
|
+
const validScopes = new Set(payload.scope?.split(" "));
|
|
320
|
+
for (const sc of opts.scopes) if (!validScopes.has(sc)) throw new APIError("FORBIDDEN", { message: `invalid scope ${sc}` });
|
|
321
|
+
}
|
|
322
|
+
return payload;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
//#endregion
|
|
326
|
+
export { validateAuthorizationCode as a, refreshAccessToken as c, getOAuth2Tokens as d, clientCredentialsToken as f, createAuthorizationCodeRequest as i, createAuthorizationURL as l, verifyAccessToken as n, validateToken as o, createClientCredentialsTokenRequest as p, verifyJwsAccessToken as r, createRefreshAccessTokenRequest as s, getJwks as t, generateCodeChallenge as u };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $ as AccountStatus, $t as GoogleProfile, A as PolarOptions, At as linear, B as LineIdTokenPayload, Bt as TwitchOptions, C as SocialProviderListEnum, Cn as atlassian, Ct as gitlab, D as VercelOptions, Dn as apple, Dt as LinearOptions, E as socialProviders, En as AppleProfile, Et as linkedin, F as PayPalTokenResponse, Ft as DropboxProfile, G as NaverProfile, Gt as spotify, H as LineUserInfo, Ht as twitch, I as paypal, It as dropbox, J as KakaoProfile, Jt as slack, K as naver, Kt as SlackOptions, L as PaybinOptions, Lt as TwitterOption, M as polar, Mt as KickProfile, N as PayPalOptions, Nt as kick, O as VercelProfile, On as getApplePublicKey, Ot as LinearProfile, P as PayPalProfile, Pt as DropboxOptions, Q as notion, Qt as GoogleOptions, R as PaybinProfile, Rt as TwitterProfile, S as SocialProviderList, Sn as AtlassianProfile, St as GitlabProfile, T as socialProviderList, Tn as AppleOptions, Tt as LinkedInProfile, U as line, Ut as SpotifyOptions, V as LineOptions, Vt as TwitchProfile, W as NaverOptions, Wt as SpotifyProfile, X as NotionOptions, Xt as HuggingFaceProfile, Y as kakao, Yt as HuggingFaceOptions, Z as NotionProfile, Zt as huggingface, _n as CognitoOptions, _t as reddit, an as GithubOptions, at as zoom, bn as getCognitoPublicKey, bt as tiktok, cn as FigmaOptions, ct as vk, dn as FacebookOptions, dt as salesforce, en as getGooglePublicKey, et as LoginType, fn as FacebookProfile, ft as RobloxOptions, gn as discord, gt as RedditProfile, hn as DiscordProfile, ht as RedditOptions, in as microsoft, it as ZoomProfile, j as PolarProfile, jt as KickOptions, k as vercel, kt as LinearUser, ln as FigmaProfile, lt as SalesforceOptions, mn as DiscordOptions, mt as roblox, nn as MicrosoftEntraIDProfile, nt as PronounOption, on as GithubProfile, ot as VkOption, pn as facebook, pt as RobloxProfile, q as KakaoOptions, qt as SlackProfile, rn as MicrosoftOptions, rt as ZoomOptions, sn as github, st as VkProfile, tn as google, tt as PhoneNumber, un as figma, ut as SalesforceProfile, vn as CognitoProfile, vt as TiktokOptions, w as SocialProviders, wn as AppleNonConformUser, wt as LinkedInOptions, x as SocialProvider, xn as AtlassianOptions, xt as GitlabOptions, yn as cognito, yt as TiktokProfile, z as paybin, zt as twitter } from "../index-
|
|
1
|
+
import { $ as AccountStatus, $t as GoogleProfile, A as PolarOptions, At as linear, B as LineIdTokenPayload, Bt as TwitchOptions, C as SocialProviderListEnum, Cn as atlassian, Ct as gitlab, D as VercelOptions, Dn as apple, Dt as LinearOptions, E as socialProviders, En as AppleProfile, Et as linkedin, F as PayPalTokenResponse, Ft as DropboxProfile, G as NaverProfile, Gt as spotify, H as LineUserInfo, Ht as twitch, I as paypal, It as dropbox, J as KakaoProfile, Jt as slack, K as naver, Kt as SlackOptions, L as PaybinOptions, Lt as TwitterOption, M as polar, Mt as KickProfile, N as PayPalOptions, Nt as kick, O as VercelProfile, On as getApplePublicKey, Ot as LinearProfile, P as PayPalProfile, Pt as DropboxOptions, Q as notion, Qt as GoogleOptions, R as PaybinProfile, Rt as TwitterProfile, S as SocialProviderList, Sn as AtlassianProfile, St as GitlabProfile, T as socialProviderList, Tn as AppleOptions, Tt as LinkedInProfile, U as line, Ut as SpotifyOptions, V as LineOptions, Vt as TwitchProfile, W as NaverOptions, Wt as SpotifyProfile, X as NotionOptions, Xt as HuggingFaceProfile, Y as kakao, Yt as HuggingFaceOptions, Z as NotionProfile, Zt as huggingface, _n as CognitoOptions, _t as reddit, an as GithubOptions, at as zoom, bn as getCognitoPublicKey, bt as tiktok, cn as FigmaOptions, ct as vk, dn as FacebookOptions, dt as salesforce, en as getGooglePublicKey, et as LoginType, fn as FacebookProfile, ft as RobloxOptions, gn as discord, gt as RedditProfile, hn as DiscordProfile, ht as RedditOptions, in as microsoft, it as ZoomProfile, j as PolarProfile, jt as KickOptions, k as vercel, kt as LinearUser, ln as FigmaProfile, lt as SalesforceOptions, mn as DiscordOptions, mt as roblox, nn as MicrosoftEntraIDProfile, nt as PronounOption, on as GithubProfile, ot as VkOption, pn as facebook, pt as RobloxProfile, q as KakaoOptions, qt as SlackProfile, rn as MicrosoftOptions, rt as ZoomOptions, sn as github, st as VkProfile, tn as google, tt as PhoneNumber, un as figma, ut as SalesforceProfile, vn as CognitoProfile, vt as TiktokOptions, w as SocialProviders, wn as AppleNonConformUser, wt as LinkedInOptions, x as SocialProvider, xn as AtlassianOptions, xt as GitlabOptions, yn as cognito, yt as TiktokProfile, z as paybin, zt as twitter } from "../index-CBdZH5fV.mjs";
|
|
2
2
|
export { AccountStatus, AppleNonConformUser, AppleOptions, AppleProfile, AtlassianOptions, AtlassianProfile, CognitoOptions, CognitoProfile, DiscordOptions, DiscordProfile, DropboxOptions, DropboxProfile, FacebookOptions, FacebookProfile, FigmaOptions, FigmaProfile, GithubOptions, GithubProfile, GitlabOptions, GitlabProfile, GoogleOptions, GoogleProfile, HuggingFaceOptions, HuggingFaceProfile, KakaoOptions, KakaoProfile, KickOptions, KickProfile, LineIdTokenPayload, LineOptions, LineUserInfo, LinearOptions, LinearProfile, LinearUser, LinkedInOptions, LinkedInProfile, LoginType, MicrosoftEntraIDProfile, MicrosoftOptions, NaverOptions, NaverProfile, NotionOptions, NotionProfile, PayPalOptions, PayPalProfile, PayPalTokenResponse, PaybinOptions, PaybinProfile, PhoneNumber, PolarOptions, PolarProfile, PronounOption, RedditOptions, RedditProfile, RobloxOptions, RobloxProfile, SalesforceOptions, SalesforceProfile, SlackOptions, SlackProfile, SocialProvider, SocialProviderList, SocialProviderListEnum, SocialProviders, SpotifyOptions, SpotifyProfile, TiktokOptions, TiktokProfile, TwitchOptions, TwitchProfile, TwitterOption, TwitterProfile, VercelOptions, VercelProfile, VkOption, VkProfile, ZoomOptions, ZoomProfile, apple, atlassian, cognito, discord, dropbox, facebook, figma, getApplePublicKey, getCognitoPublicKey, getGooglePublicKey, github, gitlab, google, huggingface, kakao, kick, line, linear, linkedin, microsoft, naver, notion, paybin, paypal, polar, reddit, roblox, salesforce, slack, socialProviderList, socialProviders, spotify, tiktok, twitch, twitter, vercel, vk, zoom };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { i as logger } from "../env-DbssmzoK.mjs";
|
|
2
2
|
import "../utils-NloIXYE0.mjs";
|
|
3
3
|
import { t as BetterAuthError } from "../error-CzMAIrPb.mjs";
|
|
4
|
-
import { a as
|
|
4
|
+
import { a as validateAuthorizationCode, c as refreshAccessToken, d as getOAuth2Tokens, l as createAuthorizationURL, u as generateCodeChallenge } from "../oauth2-BjWM15hm.mjs";
|
|
5
5
|
import * as z from "zod";
|
|
6
6
|
import { base64 } from "@better-auth/utils/base64";
|
|
7
7
|
import { betterFetch } from "@better-fetch/fetch";
|
|
@@ -203,7 +203,7 @@ const cognito = (options) => {
|
|
|
203
203
|
];
|
|
204
204
|
if (options.scope) _scopes.push(...options.scope);
|
|
205
205
|
if (scopes) _scopes.push(...scopes);
|
|
206
|
-
|
|
206
|
+
const url = await createAuthorizationURL({
|
|
207
207
|
id: "cognito",
|
|
208
208
|
options: { ...options },
|
|
209
209
|
authorizationEndpoint,
|
|
@@ -213,6 +213,15 @@ const cognito = (options) => {
|
|
|
213
213
|
redirectURI,
|
|
214
214
|
prompt: options.prompt
|
|
215
215
|
});
|
|
216
|
+
const scopeValue = url.searchParams.get("scope");
|
|
217
|
+
if (scopeValue) {
|
|
218
|
+
url.searchParams.delete("scope");
|
|
219
|
+
const encodedScope = encodeURIComponent(scopeValue);
|
|
220
|
+
const urlString = url.toString();
|
|
221
|
+
const separator = urlString.includes("?") ? "&" : "?";
|
|
222
|
+
return new URL(`${urlString}${separator}scope=${encodedScope}`);
|
|
223
|
+
}
|
|
224
|
+
return url;
|
|
216
225
|
},
|
|
217
226
|
validateAuthorizationCode: async ({ code, codeVerifier, redirectURI }) => {
|
|
218
227
|
return validateAuthorizationCode({
|
package/package.json
CHANGED
|
@@ -474,9 +474,19 @@ export const createAdapterFactory =
|
|
|
474
474
|
const transformWhereClause = <W extends Where[] | undefined>({
|
|
475
475
|
model,
|
|
476
476
|
where,
|
|
477
|
+
action,
|
|
477
478
|
}: {
|
|
478
479
|
where: W;
|
|
479
480
|
model: string;
|
|
481
|
+
action:
|
|
482
|
+
| "create"
|
|
483
|
+
| "update"
|
|
484
|
+
| "findOne"
|
|
485
|
+
| "findMany"
|
|
486
|
+
| "updateMany"
|
|
487
|
+
| "delete"
|
|
488
|
+
| "deleteMany"
|
|
489
|
+
| "count";
|
|
480
490
|
}): W extends undefined ? undefined : CleanedWhere[] => {
|
|
481
491
|
if (!where) return undefined as any;
|
|
482
492
|
const newMappedKeys = config.mapKeysTransformInput ?? {};
|
|
@@ -562,6 +572,18 @@ export const createAdapterFactory =
|
|
|
562
572
|
}
|
|
563
573
|
}
|
|
564
574
|
|
|
575
|
+
if (config.customTransformInput) {
|
|
576
|
+
newValue = config.customTransformInput({
|
|
577
|
+
data: newValue,
|
|
578
|
+
fieldAttributes: fieldAttr,
|
|
579
|
+
field: fieldName,
|
|
580
|
+
model: getModelName(model),
|
|
581
|
+
schema,
|
|
582
|
+
options,
|
|
583
|
+
action,
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
|
|
565
587
|
return {
|
|
566
588
|
operator,
|
|
567
589
|
connector,
|
|
@@ -727,6 +749,7 @@ export const createAdapterFactory =
|
|
|
727
749
|
connector: "AND",
|
|
728
750
|
},
|
|
729
751
|
],
|
|
752
|
+
action: "findOne",
|
|
730
753
|
});
|
|
731
754
|
try {
|
|
732
755
|
if (joinConfig.relation === "one-to-one") {
|
|
@@ -886,6 +909,7 @@ export const createAdapterFactory =
|
|
|
886
909
|
const where = transformWhereClause({
|
|
887
910
|
model: unsafeModel,
|
|
888
911
|
where: unsafeWhere,
|
|
912
|
+
action: "update",
|
|
889
913
|
});
|
|
890
914
|
debugLog(
|
|
891
915
|
{ method: "update" },
|
|
@@ -946,6 +970,7 @@ export const createAdapterFactory =
|
|
|
946
970
|
const where = transformWhereClause({
|
|
947
971
|
model: unsafeModel,
|
|
948
972
|
where: unsafeWhere,
|
|
973
|
+
action: "updateMany",
|
|
949
974
|
});
|
|
950
975
|
unsafeModel = getDefaultModelName(unsafeModel);
|
|
951
976
|
debugLog(
|
|
@@ -1001,6 +1026,7 @@ export const createAdapterFactory =
|
|
|
1001
1026
|
const where = transformWhereClause({
|
|
1002
1027
|
model: unsafeModel,
|
|
1003
1028
|
where: unsafeWhere,
|
|
1029
|
+
action: "findOne",
|
|
1004
1030
|
});
|
|
1005
1031
|
unsafeModel = getDefaultModelName(unsafeModel);
|
|
1006
1032
|
let join: JoinConfig | undefined;
|
|
@@ -1078,6 +1104,7 @@ export const createAdapterFactory =
|
|
|
1078
1104
|
const where = transformWhereClause({
|
|
1079
1105
|
model: unsafeModel,
|
|
1080
1106
|
where: unsafeWhere,
|
|
1107
|
+
action: "findMany",
|
|
1081
1108
|
});
|
|
1082
1109
|
unsafeModel = getDefaultModelName(unsafeModel);
|
|
1083
1110
|
let join: JoinConfig | undefined;
|
|
@@ -1151,6 +1178,7 @@ export const createAdapterFactory =
|
|
|
1151
1178
|
const where = transformWhereClause({
|
|
1152
1179
|
model: unsafeModel,
|
|
1153
1180
|
where: unsafeWhere,
|
|
1181
|
+
action: "delete",
|
|
1154
1182
|
});
|
|
1155
1183
|
unsafeModel = getDefaultModelName(unsafeModel);
|
|
1156
1184
|
debugLog(
|
|
@@ -1183,6 +1211,7 @@ export const createAdapterFactory =
|
|
|
1183
1211
|
const where = transformWhereClause({
|
|
1184
1212
|
model: unsafeModel,
|
|
1185
1213
|
where: unsafeWhere,
|
|
1214
|
+
action: "deleteMany",
|
|
1186
1215
|
});
|
|
1187
1216
|
unsafeModel = getDefaultModelName(unsafeModel);
|
|
1188
1217
|
debugLog(
|
|
@@ -1216,6 +1245,7 @@ export const createAdapterFactory =
|
|
|
1216
1245
|
const where = transformWhereClause({
|
|
1217
1246
|
model: unsafeModel,
|
|
1218
1247
|
where: unsafeWhere,
|
|
1248
|
+
action: "count",
|
|
1219
1249
|
});
|
|
1220
1250
|
unsafeModel = getDefaultModelName(unsafeModel);
|
|
1221
1251
|
debugLog(
|
package/src/db/adapter/index.ts
CHANGED
|
@@ -203,7 +203,15 @@ export interface DBAdapterFactoryConfig<
|
|
|
203
203
|
/**
|
|
204
204
|
* The action which was called from the adapter.
|
|
205
205
|
*/
|
|
206
|
-
action:
|
|
206
|
+
action:
|
|
207
|
+
| "create"
|
|
208
|
+
| "update"
|
|
209
|
+
| "findOne"
|
|
210
|
+
| "findMany"
|
|
211
|
+
| "updateMany"
|
|
212
|
+
| "delete"
|
|
213
|
+
| "deleteMany"
|
|
214
|
+
| "count";
|
|
207
215
|
/**
|
|
208
216
|
* The model name.
|
|
209
217
|
*/
|
package/src/db/adapter/types.ts
CHANGED
|
@@ -111,9 +111,19 @@ export type AdapterFactoryCustomizeAdapterCreator = (config: {
|
|
|
111
111
|
transformWhereClause: <W extends Where[] | undefined>({
|
|
112
112
|
model,
|
|
113
113
|
where,
|
|
114
|
+
action,
|
|
114
115
|
}: {
|
|
115
116
|
where: W;
|
|
116
117
|
model: string;
|
|
118
|
+
action:
|
|
119
|
+
| "create"
|
|
120
|
+
| "update"
|
|
121
|
+
| "findOne"
|
|
122
|
+
| "findMany"
|
|
123
|
+
| "updateMany"
|
|
124
|
+
| "delete"
|
|
125
|
+
| "deleteMany"
|
|
126
|
+
| "count";
|
|
117
127
|
}) => W extends undefined ? undefined : CleanedWhere[];
|
|
118
128
|
}) => CustomAdapter;
|
|
119
129
|
|
package/src/oauth2/index.ts
CHANGED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { betterFetch } from "@better-fetch/fetch";
|
|
2
|
+
import { APIError } from "better-call";
|
|
3
|
+
import type {
|
|
4
|
+
JSONWebKeySet,
|
|
5
|
+
JWTPayload,
|
|
6
|
+
JWTVerifyOptions,
|
|
7
|
+
ProtectedHeaderParameters,
|
|
8
|
+
} from "jose";
|
|
9
|
+
import {
|
|
10
|
+
createLocalJWKSet,
|
|
11
|
+
decodeProtectedHeader,
|
|
12
|
+
jwtVerify,
|
|
13
|
+
UnsecuredJWT,
|
|
14
|
+
} from "jose";
|
|
15
|
+
import { logger } from "../env";
|
|
16
|
+
|
|
17
|
+
/** Last fetched jwks used locally in getJwks @internal */
|
|
18
|
+
let jwks: JSONWebKeySet | undefined;
|
|
19
|
+
|
|
20
|
+
export interface VerifyAccessTokenRemote {
|
|
21
|
+
/** Full url of the introspect endpoint. Should end with `/oauth2/introspect` */
|
|
22
|
+
introspectUrl: string;
|
|
23
|
+
/** Client Secret */
|
|
24
|
+
clientId: string;
|
|
25
|
+
/** Client Secret */
|
|
26
|
+
clientSecret: string;
|
|
27
|
+
/**
|
|
28
|
+
* Forces remote verification of a token.
|
|
29
|
+
* This ensures attached session (if applicable)
|
|
30
|
+
* is also still active.
|
|
31
|
+
*/
|
|
32
|
+
force?: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Performs local verification of an access token for your APIs.
|
|
37
|
+
*
|
|
38
|
+
* Can also be configured for remote verification.
|
|
39
|
+
*/
|
|
40
|
+
export async function verifyJwsAccessToken(
|
|
41
|
+
token: string,
|
|
42
|
+
opts: {
|
|
43
|
+
/** Jwks url or promise of a Jwks */
|
|
44
|
+
jwksFetch: string | (() => Promise<JSONWebKeySet | undefined>);
|
|
45
|
+
/** Verify options */
|
|
46
|
+
verifyOptions: JWTVerifyOptions &
|
|
47
|
+
Required<Pick<JWTVerifyOptions, "audience" | "issuer">>;
|
|
48
|
+
},
|
|
49
|
+
) {
|
|
50
|
+
try {
|
|
51
|
+
const jwks = await getJwks(token, opts);
|
|
52
|
+
const jwt = await jwtVerify<JWTPayload>(
|
|
53
|
+
token,
|
|
54
|
+
createLocalJWKSet(jwks),
|
|
55
|
+
opts.verifyOptions,
|
|
56
|
+
);
|
|
57
|
+
// Return the JWT payload in introspection format
|
|
58
|
+
// https://datatracker.ietf.org/doc/html/rfc7662#section-2.2
|
|
59
|
+
if (jwt.payload.azp) {
|
|
60
|
+
jwt.payload.client_id = jwt.payload.azp;
|
|
61
|
+
}
|
|
62
|
+
return jwt.payload;
|
|
63
|
+
} catch (error) {
|
|
64
|
+
if (error instanceof Error) throw error;
|
|
65
|
+
throw new Error(error as unknown as string);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export async function getJwks(
|
|
70
|
+
token: string,
|
|
71
|
+
opts: {
|
|
72
|
+
/** Jwks url or promise of a Jwks */
|
|
73
|
+
jwksFetch: string | (() => Promise<JSONWebKeySet | undefined>);
|
|
74
|
+
},
|
|
75
|
+
) {
|
|
76
|
+
// Attempt to decode the token and find a matching kid in jwks
|
|
77
|
+
let jwtHeaders: ProtectedHeaderParameters | undefined;
|
|
78
|
+
try {
|
|
79
|
+
jwtHeaders = decodeProtectedHeader(token);
|
|
80
|
+
} catch (error) {
|
|
81
|
+
if (error instanceof Error) throw error;
|
|
82
|
+
throw new Error(error as unknown as string);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!jwtHeaders.kid) throw new Error("Missing jwt kid");
|
|
86
|
+
|
|
87
|
+
// Fetch jwks if not set or has a different kid than the one stored
|
|
88
|
+
if (!jwks || !jwks.keys.find((jwk) => jwk.kid === jwtHeaders.kid)) {
|
|
89
|
+
jwks =
|
|
90
|
+
typeof opts.jwksFetch === "string"
|
|
91
|
+
? await betterFetch<JSONWebKeySet>(opts.jwksFetch, {
|
|
92
|
+
headers: {
|
|
93
|
+
Accept: "application/json",
|
|
94
|
+
},
|
|
95
|
+
}).then(async (res) => {
|
|
96
|
+
if (res.error)
|
|
97
|
+
throw new Error(
|
|
98
|
+
`Jwks failed: ${res.error.message ?? res.error.statusText}`,
|
|
99
|
+
);
|
|
100
|
+
return res.data;
|
|
101
|
+
})
|
|
102
|
+
: await opts.jwksFetch();
|
|
103
|
+
if (!jwks) throw new Error("No jwks found");
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return jwks;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Performs local verification of an access token for your API.
|
|
111
|
+
*
|
|
112
|
+
* Can also be configured for remote verification.
|
|
113
|
+
*/
|
|
114
|
+
export async function verifyAccessToken(
|
|
115
|
+
token: string,
|
|
116
|
+
opts: {
|
|
117
|
+
/** Verify options */
|
|
118
|
+
verifyOptions: JWTVerifyOptions &
|
|
119
|
+
Required<Pick<JWTVerifyOptions, "audience" | "issuer">>;
|
|
120
|
+
/** Scopes to additionally verify. Token must include all but not exact. */
|
|
121
|
+
scopes?: string[];
|
|
122
|
+
/** Required to verify access token locally */
|
|
123
|
+
jwksUrl?: string;
|
|
124
|
+
/** If provided, can verify a token remotely */
|
|
125
|
+
remoteVerify?: VerifyAccessTokenRemote;
|
|
126
|
+
},
|
|
127
|
+
) {
|
|
128
|
+
let payload: JWTPayload | undefined;
|
|
129
|
+
// Locally verify
|
|
130
|
+
if (opts.jwksUrl && !opts?.remoteVerify?.force) {
|
|
131
|
+
try {
|
|
132
|
+
payload = await verifyJwsAccessToken(token, {
|
|
133
|
+
jwksFetch: opts.jwksUrl,
|
|
134
|
+
verifyOptions: opts.verifyOptions,
|
|
135
|
+
});
|
|
136
|
+
} catch (error) {
|
|
137
|
+
if (error instanceof Error) {
|
|
138
|
+
if (error.name === "TypeError" || error.name === "JWSInvalid") {
|
|
139
|
+
// likely an opaque token (continue)
|
|
140
|
+
} else if (error.name === "JWTExpired") {
|
|
141
|
+
throw new APIError("UNAUTHORIZED", {
|
|
142
|
+
message: "token expired",
|
|
143
|
+
});
|
|
144
|
+
} else if (error.name === "JWTInvalid") {
|
|
145
|
+
throw new APIError("UNAUTHORIZED", {
|
|
146
|
+
message: "token invalid",
|
|
147
|
+
});
|
|
148
|
+
} else {
|
|
149
|
+
throw error;
|
|
150
|
+
}
|
|
151
|
+
} else {
|
|
152
|
+
throw new Error(error as unknown as string);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Remote verify
|
|
158
|
+
if (opts?.remoteVerify) {
|
|
159
|
+
const { data: introspect, error: introspectError } = await betterFetch<
|
|
160
|
+
JWTPayload & {
|
|
161
|
+
active: boolean;
|
|
162
|
+
}
|
|
163
|
+
>(opts.remoteVerify.introspectUrl, {
|
|
164
|
+
method: "POST",
|
|
165
|
+
headers: {
|
|
166
|
+
Accept: "application/json",
|
|
167
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
168
|
+
},
|
|
169
|
+
body: new URLSearchParams({
|
|
170
|
+
client_id: opts.remoteVerify.clientId,
|
|
171
|
+
client_secret: opts.remoteVerify.clientSecret,
|
|
172
|
+
token,
|
|
173
|
+
token_type_hint: "access_token",
|
|
174
|
+
}).toString(),
|
|
175
|
+
});
|
|
176
|
+
if (introspectError)
|
|
177
|
+
logger.error(
|
|
178
|
+
`Introspection failed: ${introspectError.message ?? introspectError.statusText}`,
|
|
179
|
+
);
|
|
180
|
+
if (!introspect)
|
|
181
|
+
throw new APIError("INTERNAL_SERVER_ERROR", {
|
|
182
|
+
message: "introspection failed",
|
|
183
|
+
});
|
|
184
|
+
if (!introspect.active)
|
|
185
|
+
throw new APIError("UNAUTHORIZED", {
|
|
186
|
+
message: "token inactive",
|
|
187
|
+
});
|
|
188
|
+
// Verifies payload using verify options (token valid through introspect)
|
|
189
|
+
try {
|
|
190
|
+
const unsecuredJwt = new UnsecuredJWT(introspect).encode();
|
|
191
|
+
const { audience: _audience, ...verifyOptions } = opts.verifyOptions;
|
|
192
|
+
const verify = introspect.aud
|
|
193
|
+
? UnsecuredJWT.decode(unsecuredJwt, opts.verifyOptions)
|
|
194
|
+
: UnsecuredJWT.decode(unsecuredJwt, verifyOptions);
|
|
195
|
+
payload = verify.payload;
|
|
196
|
+
} catch (error) {
|
|
197
|
+
throw new Error(error as unknown as string);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (!payload)
|
|
202
|
+
throw new APIError("UNAUTHORIZED", {
|
|
203
|
+
message: `no token payload`,
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
// Check scopes if provided
|
|
207
|
+
if (opts.scopes) {
|
|
208
|
+
const validScopes = new Set(
|
|
209
|
+
(payload.scope as string | undefined)?.split(" "),
|
|
210
|
+
);
|
|
211
|
+
for (const sc of opts.scopes) {
|
|
212
|
+
if (!validScopes.has(sc)) {
|
|
213
|
+
throw new APIError("FORBIDDEN", {
|
|
214
|
+
message: `invalid scope ${sc}`,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return payload;
|
|
221
|
+
}
|
|
@@ -92,6 +92,17 @@ export const cognito = (options: CognitoOptions) => {
|
|
|
92
92
|
redirectURI,
|
|
93
93
|
prompt: options.prompt,
|
|
94
94
|
});
|
|
95
|
+
// AWS Cognito requires scopes to be encoded with %20 instead of +
|
|
96
|
+
// URLSearchParams encodes spaces as + by default, so we need to fix this
|
|
97
|
+
const scopeValue = url.searchParams.get("scope");
|
|
98
|
+
if (scopeValue) {
|
|
99
|
+
url.searchParams.delete("scope");
|
|
100
|
+
const encodedScope = encodeURIComponent(scopeValue);
|
|
101
|
+
// Manually append the scope with proper encoding to the URL
|
|
102
|
+
const urlString = url.toString();
|
|
103
|
+
const separator = urlString.includes("?") ? "&" : "?";
|
|
104
|
+
return new URL(`${urlString}${separator}scope=${encodedScope}`);
|
|
105
|
+
}
|
|
95
106
|
return url;
|
|
96
107
|
},
|
|
97
108
|
|
|
@@ -994,17 +994,9 @@ export type BetterAuthOptions = {
|
|
|
994
994
|
| undefined;
|
|
995
995
|
/**
|
|
996
996
|
* List of trusted origins.
|
|
997
|
-
*
|
|
998
|
-
* @param request - The request object.
|
|
999
|
-
* It'll be undefined if no request was
|
|
1000
|
-
* made. Like during a create context call
|
|
1001
|
-
* or `auth.api` call.
|
|
1002
|
-
*
|
|
1003
|
-
* Trusted origins will be dynamically
|
|
1004
|
-
* calculated based on the request.
|
|
1005
997
|
*/
|
|
1006
998
|
trustedOrigins?:
|
|
1007
|
-
| (string[] | ((request
|
|
999
|
+
| (string[] | ((request: Request) => Awaitable<string[]>))
|
|
1008
1000
|
| undefined;
|
|
1009
1001
|
/**
|
|
1010
1002
|
* Rate limiting configuration
|