@better-auth/core 1.6.18 → 1.6.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/dist/context/global.mjs +1 -1
- package/dist/context/transaction.d.mts +7 -4
- package/dist/context/transaction.mjs +6 -3
- package/dist/db/adapter/factory.mjs +9 -2
- package/dist/error/index.d.mts +7 -0
- package/dist/instrumentation/tracer.mjs +1 -1
- package/dist/types/init-options.d.mts +6 -2
- package/package.json +5 -5
- package/src/context/transaction.ts +45 -12
- package/src/db/adapter/factory.ts +32 -7
- package/src/error/index.ts +9 -0
- package/src/types/init-options.ts +6 -2
package/dist/context/global.mjs
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { DBAdapter, DBTransactionAdapter } from "../db/adapter/index.mjs";
|
|
2
|
+
import { BetterAuthOptions } from "../types/init-options.mjs";
|
|
2
3
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3
4
|
|
|
4
5
|
//#region src/context/transaction.d.ts
|
|
6
|
+
type StoredAdapter = DBTransactionAdapter<BetterAuthOptions>;
|
|
5
7
|
type HookContext = {
|
|
6
|
-
adapter:
|
|
8
|
+
adapter: StoredAdapter;
|
|
7
9
|
pendingHooks: Array<() => Promise<void>>;
|
|
10
|
+
isTransactionActive: boolean;
|
|
8
11
|
};
|
|
9
12
|
/**
|
|
10
13
|
* This is for internal use only. Most users should use `getCurrentAdapter` instead.
|
|
@@ -12,9 +15,9 @@ type HookContext = {
|
|
|
12
15
|
* It is exposed for advanced use cases where you need direct access to the AsyncLocalStorage instance.
|
|
13
16
|
*/
|
|
14
17
|
declare const getCurrentDBAdapterAsyncLocalStorage: () => Promise<AsyncLocalStorage<HookContext>>;
|
|
15
|
-
declare const getCurrentAdapter: (fallback: DBTransactionAdapter) => Promise<DBTransactionAdapter
|
|
16
|
-
declare const runWithAdapter: <R>(adapter: DBAdapter
|
|
17
|
-
declare const runWithTransaction: <R>(adapter: DBAdapter
|
|
18
|
+
declare const getCurrentAdapter: <Options extends BetterAuthOptions = BetterAuthOptions>(fallback: DBTransactionAdapter<Options>) => Promise<DBTransactionAdapter<Options>>;
|
|
19
|
+
declare const runWithAdapter: <R, Options extends BetterAuthOptions = BetterAuthOptions>(adapter: DBAdapter<Options>, fn: () => R) => Promise<R>;
|
|
20
|
+
declare const runWithTransaction: <R, Options extends BetterAuthOptions = BetterAuthOptions>(adapter: DBAdapter<Options>, fn: () => R) => Promise<R>;
|
|
18
21
|
/**
|
|
19
22
|
* Queue a hook to be executed after the current transaction commits.
|
|
20
23
|
* If not in a transaction, the hook will execute immediately.
|
|
@@ -35,7 +35,8 @@ const runWithAdapter = async (adapter, fn) => {
|
|
|
35
35
|
try {
|
|
36
36
|
result = await als.run({
|
|
37
37
|
adapter,
|
|
38
|
-
pendingHooks
|
|
38
|
+
pendingHooks,
|
|
39
|
+
isTransactionActive: false
|
|
39
40
|
}, fn);
|
|
40
41
|
} catch (err) {
|
|
41
42
|
error = err;
|
|
@@ -50,9 +51,10 @@ const runWithAdapter = async (adapter, fn) => {
|
|
|
50
51
|
});
|
|
51
52
|
};
|
|
52
53
|
const runWithTransaction = async (adapter, fn) => {
|
|
53
|
-
let called =
|
|
54
|
+
let called = false;
|
|
54
55
|
return ensureAsyncStorage().then(async (als) => {
|
|
55
56
|
called = true;
|
|
57
|
+
if (als.getStore()?.isTransactionActive) return fn();
|
|
56
58
|
const pendingHooks = [];
|
|
57
59
|
let result;
|
|
58
60
|
let error;
|
|
@@ -61,7 +63,8 @@ const runWithTransaction = async (adapter, fn) => {
|
|
|
61
63
|
result = await adapter.transaction(async (trx) => {
|
|
62
64
|
return als.run({
|
|
63
65
|
adapter: trx,
|
|
64
|
-
pendingHooks
|
|
66
|
+
pendingHooks,
|
|
67
|
+
isTransactionActive: true
|
|
65
68
|
}, fn);
|
|
66
69
|
});
|
|
67
70
|
} catch (e) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getCurrentAdapter, runWithTransaction } from "../../context/transaction.mjs";
|
|
1
2
|
import { BetterAuthError } from "../../error/index.mjs";
|
|
2
3
|
import { getAuthTables } from "../get-tables.mjs";
|
|
3
4
|
import { getColorDepth } from "../../env/color-depth.mjs";
|
|
@@ -705,7 +706,8 @@ const createAdapterFactory = ({ adapter: customAdapter, config: cfg }) => (optio
|
|
|
705
706
|
res = await withSpan(`db consumeOne ${model}`, {
|
|
706
707
|
[ATTR_DB_OPERATION_NAME]: "consumeOne",
|
|
707
708
|
[ATTR_DB_COLLECTION_NAME]: model
|
|
708
|
-
}, () => adapter
|
|
709
|
+
}, () => runWithTransaction(adapter, async () => {
|
|
710
|
+
const trx = await getCurrentAdapter(adapter);
|
|
709
711
|
const target = (await trx.findMany({
|
|
710
712
|
model: unsafeModel,
|
|
711
713
|
where: unsafeWhere,
|
|
@@ -740,6 +742,9 @@ const createAdapterFactory = ({ adapter: customAdapter, config: cfg }) => (optio
|
|
|
740
742
|
return transformed;
|
|
741
743
|
},
|
|
742
744
|
incrementOne: async ({ model: unsafeModel, where: unsafeWhere, increment: unsafeIncrement, set: unsafeSet }) => {
|
|
745
|
+
const hasIncrement = Object.keys(unsafeIncrement).length > 0;
|
|
746
|
+
const hasSet = !!unsafeSet && Object.keys(unsafeSet).length > 0;
|
|
747
|
+
if (!hasIncrement && !hasSet) throw new BetterAuthError("incrementOne requires a non-empty `increment` or `set`; both were empty.");
|
|
743
748
|
transactionId++;
|
|
744
749
|
const thisTransactionId = transactionId;
|
|
745
750
|
const model = getModelName(unsafeModel);
|
|
@@ -767,6 +772,7 @@ const createAdapterFactory = ({ adapter: customAdapter, config: cfg }) => (optio
|
|
|
767
772
|
let set;
|
|
768
773
|
if (unsafeSet && !config.disableTransformInput) set = await transformInput(unsafeSet, unsafeModel, "update");
|
|
769
774
|
else set = unsafeSet;
|
|
775
|
+
if (Object.keys(increment).length === 0 && (!set || Object.keys(set).length === 0)) throw new BetterAuthError("incrementOne resolved to an empty update: every increment/set field was unknown to the schema or transformed away.");
|
|
770
776
|
res = await withSpan(`db incrementOne ${model}`, {
|
|
771
777
|
[ATTR_DB_OPERATION_NAME]: "incrementOne",
|
|
772
778
|
[ATTR_DB_COLLECTION_NAME]: model
|
|
@@ -780,7 +786,8 @@ const createAdapterFactory = ({ adapter: customAdapter, config: cfg }) => (optio
|
|
|
780
786
|
res = await withSpan(`db incrementOne ${model}`, {
|
|
781
787
|
[ATTR_DB_OPERATION_NAME]: "incrementOne",
|
|
782
788
|
[ATTR_DB_COLLECTION_NAME]: model
|
|
783
|
-
}, () => adapter
|
|
789
|
+
}, () => runWithTransaction(adapter, async () => {
|
|
790
|
+
const trx = await getCurrentAdapter(adapter);
|
|
784
791
|
const target = (await trx.findMany({
|
|
785
792
|
model: unsafeModel,
|
|
786
793
|
where: unsafeWhere,
|
package/dist/error/index.d.mts
CHANGED
|
@@ -7,7 +7,14 @@ declare class BetterAuthError extends Error {
|
|
|
7
7
|
cause?: unknown | undefined;
|
|
8
8
|
});
|
|
9
9
|
}
|
|
10
|
+
type BaseAPIErrorInstance = InstanceType<typeof APIError$1>;
|
|
10
11
|
declare class APIError extends APIError$1 {
|
|
12
|
+
status: BaseAPIErrorInstance["status"];
|
|
13
|
+
body: BaseAPIErrorInstance["body"];
|
|
14
|
+
headers: BaseAPIErrorInstance["headers"];
|
|
15
|
+
statusCode: BaseAPIErrorInstance["statusCode"];
|
|
16
|
+
message: string;
|
|
17
|
+
errorStack: BaseAPIErrorInstance["errorStack"];
|
|
11
18
|
constructor(...args: ConstructorParameters<typeof APIError$1>);
|
|
12
19
|
static fromStatus(status: ConstructorParameters<typeof APIError$1>[0], body?: ConstructorParameters<typeof APIError$1>[1]): APIError;
|
|
13
20
|
static from(status: ConstructorParameters<typeof APIError$1>[0], error: {
|
|
@@ -2,7 +2,7 @@ import { ATTR_HTTP_RESPONSE_STATUS_CODE } from "./attributes.mjs";
|
|
|
2
2
|
import { getOpenTelemetryAPI } from "./api.mjs";
|
|
3
3
|
//#region src/instrumentation/tracer.ts
|
|
4
4
|
const INSTRUMENTATION_SCOPE = "better-auth";
|
|
5
|
-
const INSTRUMENTATION_VERSION = "1.6.
|
|
5
|
+
const INSTRUMENTATION_VERSION = "1.6.20";
|
|
6
6
|
/**
|
|
7
7
|
* Better-auth uses `throw ctx.redirect(url)` for flow control (e.g. OAuth
|
|
8
8
|
* callbacks). These are APIErrors with 3xx status codes and should not be
|
|
@@ -1033,9 +1033,13 @@ type BetterAuthOptions = {
|
|
|
1033
1033
|
*/
|
|
1034
1034
|
storeStateStrategy?: "database" | "cookie";
|
|
1035
1035
|
/**
|
|
1036
|
-
* Store account data after
|
|
1036
|
+
* Store provider account data after an OAuth flow in an encrypted
|
|
1037
|
+
* cookie. This includes OAuth token material such as access tokens,
|
|
1038
|
+
* refresh tokens, ID tokens, scopes, and token expiry.
|
|
1037
1039
|
*
|
|
1038
|
-
* This is useful for database-less
|
|
1040
|
+
* This is useful for database-less flows, but large provider tokens can
|
|
1041
|
+
* still hit browser or proxy cookie/header limits even though Better Auth
|
|
1042
|
+
* chunks oversized account cookies.
|
|
1039
1043
|
*
|
|
1040
1044
|
* @default false
|
|
1041
1045
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-auth/core",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.20",
|
|
4
4
|
"description": "The most comprehensive authentication framework for TypeScript.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -152,8 +152,8 @@
|
|
|
152
152
|
"zod": "^4.3.6"
|
|
153
153
|
},
|
|
154
154
|
"devDependencies": {
|
|
155
|
-
"@better-auth/utils": "0.4.
|
|
156
|
-
"@better-fetch/fetch": "1.3.
|
|
155
|
+
"@better-auth/utils": "0.4.2",
|
|
156
|
+
"@better-fetch/fetch": "1.3.1",
|
|
157
157
|
"@opentelemetry/api": "^1.9.0",
|
|
158
158
|
"@opentelemetry/sdk-trace-base": "^1.30.0",
|
|
159
159
|
"@opentelemetry/sdk-trace-node": "^1.30.0",
|
|
@@ -165,8 +165,8 @@
|
|
|
165
165
|
"tsdown": "0.21.1"
|
|
166
166
|
},
|
|
167
167
|
"peerDependencies": {
|
|
168
|
-
"@better-auth/utils": "0.4.
|
|
169
|
-
"@better-fetch/fetch": "1.3.
|
|
168
|
+
"@better-auth/utils": "0.4.2",
|
|
169
|
+
"@better-fetch/fetch": "1.3.1",
|
|
170
170
|
"@opentelemetry/api": "^1.9.0",
|
|
171
171
|
"better-call": "1.3.6",
|
|
172
172
|
"@cloudflare/workers-types": ">=4",
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import type { AsyncLocalStorage } from "node:async_hooks";
|
|
2
2
|
import { getAsyncLocalStorage } from "@better-auth/core/async_hooks";
|
|
3
3
|
import type { DBAdapter, DBTransactionAdapter } from "../db/adapter";
|
|
4
|
+
import type { BetterAuthOptions } from "../types";
|
|
4
5
|
import { __getBetterAuthGlobal } from "./global";
|
|
5
6
|
|
|
7
|
+
type StoredAdapter = DBTransactionAdapter<BetterAuthOptions>;
|
|
8
|
+
|
|
6
9
|
type HookContext = {
|
|
7
|
-
adapter:
|
|
10
|
+
adapter: StoredAdapter;
|
|
8
11
|
pendingHooks: Array<() => Promise<void>>;
|
|
12
|
+
isTransactionActive: boolean;
|
|
9
13
|
};
|
|
10
14
|
|
|
11
15
|
const ensureAsyncStorage = async () => {
|
|
@@ -27,21 +31,29 @@ export const getCurrentDBAdapterAsyncLocalStorage = async () => {
|
|
|
27
31
|
return ensureAsyncStorage();
|
|
28
32
|
};
|
|
29
33
|
|
|
30
|
-
export const getCurrentAdapter = async
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
export const getCurrentAdapter = async <
|
|
35
|
+
Options extends BetterAuthOptions = BetterAuthOptions,
|
|
36
|
+
>(
|
|
37
|
+
fallback: DBTransactionAdapter<Options>,
|
|
38
|
+
): Promise<DBTransactionAdapter<Options>> => {
|
|
33
39
|
return ensureAsyncStorage()
|
|
34
40
|
.then((als) => {
|
|
35
41
|
const store = als.getStore();
|
|
36
|
-
return
|
|
42
|
+
return (
|
|
43
|
+
(store?.adapter as DBTransactionAdapter<Options> | undefined) ||
|
|
44
|
+
fallback
|
|
45
|
+
);
|
|
37
46
|
})
|
|
38
47
|
.catch(() => {
|
|
39
48
|
return fallback;
|
|
40
49
|
});
|
|
41
50
|
};
|
|
42
51
|
|
|
43
|
-
export const runWithAdapter = async <
|
|
44
|
-
|
|
52
|
+
export const runWithAdapter = async <
|
|
53
|
+
R,
|
|
54
|
+
Options extends BetterAuthOptions = BetterAuthOptions,
|
|
55
|
+
>(
|
|
56
|
+
adapter: DBAdapter<Options>,
|
|
45
57
|
fn: () => R,
|
|
46
58
|
): Promise<R> => {
|
|
47
59
|
let called = false;
|
|
@@ -53,7 +65,14 @@ export const runWithAdapter = async <R>(
|
|
|
53
65
|
let error: unknown;
|
|
54
66
|
let hasError = false;
|
|
55
67
|
try {
|
|
56
|
-
result = await als.run(
|
|
68
|
+
result = await als.run(
|
|
69
|
+
{
|
|
70
|
+
adapter: adapter as unknown as StoredAdapter,
|
|
71
|
+
pendingHooks,
|
|
72
|
+
isTransactionActive: false,
|
|
73
|
+
},
|
|
74
|
+
fn,
|
|
75
|
+
);
|
|
57
76
|
} catch (err) {
|
|
58
77
|
error = err;
|
|
59
78
|
hasError = true;
|
|
@@ -75,21 +94,35 @@ export const runWithAdapter = async <R>(
|
|
|
75
94
|
});
|
|
76
95
|
};
|
|
77
96
|
|
|
78
|
-
export const runWithTransaction = async <
|
|
79
|
-
|
|
97
|
+
export const runWithTransaction = async <
|
|
98
|
+
R,
|
|
99
|
+
Options extends BetterAuthOptions = BetterAuthOptions,
|
|
100
|
+
>(
|
|
101
|
+
adapter: DBAdapter<Options>,
|
|
80
102
|
fn: () => R,
|
|
81
103
|
): Promise<R> => {
|
|
82
|
-
let called =
|
|
104
|
+
let called = false;
|
|
83
105
|
return ensureAsyncStorage()
|
|
84
106
|
.then(async (als) => {
|
|
85
107
|
called = true;
|
|
108
|
+
const store = als.getStore();
|
|
109
|
+
if (store?.isTransactionActive) {
|
|
110
|
+
return fn();
|
|
111
|
+
}
|
|
86
112
|
const pendingHooks: Array<() => Promise<void>> = [];
|
|
87
113
|
let result: Awaited<R>;
|
|
88
114
|
let error: unknown;
|
|
89
115
|
let hasError = false;
|
|
90
116
|
try {
|
|
91
117
|
result = await adapter.transaction(async (trx) => {
|
|
92
|
-
return als.run(
|
|
118
|
+
return als.run(
|
|
119
|
+
{
|
|
120
|
+
adapter: trx as unknown as StoredAdapter,
|
|
121
|
+
pendingHooks,
|
|
122
|
+
isTransactionActive: true,
|
|
123
|
+
},
|
|
124
|
+
fn,
|
|
125
|
+
);
|
|
93
126
|
});
|
|
94
127
|
} catch (e) {
|
|
95
128
|
hasError = true;
|
|
@@ -3,6 +3,10 @@ import {
|
|
|
3
3
|
ATTR_DB_OPERATION_NAME,
|
|
4
4
|
withSpan,
|
|
5
5
|
} from "@better-auth/core/instrumentation";
|
|
6
|
+
import {
|
|
7
|
+
getCurrentAdapter,
|
|
8
|
+
runWithTransaction,
|
|
9
|
+
} from "../../context/transaction";
|
|
6
10
|
import { createLogger, getColorDepth, TTY_COLORS } from "../../env";
|
|
7
11
|
import { BetterAuthError } from "../../error";
|
|
8
12
|
import type { BetterAuthOptions } from "../../types";
|
|
@@ -1364,11 +1368,9 @@ export const createAdapterFactory =
|
|
|
1364
1368
|
// engines with real transaction isolation; race window narrows
|
|
1365
1369
|
// (does not close) on adapters that fall through to sequential
|
|
1366
1370
|
// execution. Remove this branch when consumeOne becomes required.
|
|
1367
|
-
//
|
|
1368
|
-
//
|
|
1369
|
-
//
|
|
1370
|
-
// adapters as as-is; make that capability explicit in the next
|
|
1371
|
-
// breaking adapter contract.
|
|
1371
|
+
// Use Better Auth's transaction context here, not a direct adapter
|
|
1372
|
+
// transaction, so callers already inside a transaction keep using
|
|
1373
|
+
// the active transaction adapter.
|
|
1372
1374
|
res = await withSpan(
|
|
1373
1375
|
`db consumeOne ${model}`,
|
|
1374
1376
|
{
|
|
@@ -1376,7 +1378,8 @@ export const createAdapterFactory =
|
|
|
1376
1378
|
[ATTR_DB_COLLECTION_NAME]: model,
|
|
1377
1379
|
},
|
|
1378
1380
|
() =>
|
|
1379
|
-
adapter
|
|
1381
|
+
runWithTransaction(adapter, async () => {
|
|
1382
|
+
const trx = await getCurrentAdapter(adapter);
|
|
1380
1383
|
const rows = await trx.findMany<Record<string, any>>({
|
|
1381
1384
|
model: unsafeModel,
|
|
1382
1385
|
where: unsafeWhere,
|
|
@@ -1447,6 +1450,16 @@ export const createAdapterFactory =
|
|
|
1447
1450
|
increment: Record<string, number>;
|
|
1448
1451
|
set?: Record<string, unknown> | undefined;
|
|
1449
1452
|
}): Promise<T | null> => {
|
|
1453
|
+
const hasIncrement = Object.keys(unsafeIncrement).length > 0;
|
|
1454
|
+
const hasSet = !!unsafeSet && Object.keys(unsafeSet).length > 0;
|
|
1455
|
+
if (!hasIncrement && !hasSet) {
|
|
1456
|
+
// An empty `increment` and empty `set` compiles to `UPDATE ... SET `
|
|
1457
|
+
// with no assignments, which is a syntax error on kysely, drizzle, and
|
|
1458
|
+
// Prisma. Fail fast with an actionable message instead.
|
|
1459
|
+
throw new BetterAuthError(
|
|
1460
|
+
"incrementOne requires a non-empty `increment` or `set`; both were empty.",
|
|
1461
|
+
);
|
|
1462
|
+
}
|
|
1450
1463
|
transactionId++;
|
|
1451
1464
|
const thisTransactionId = transactionId;
|
|
1452
1465
|
const model = getModelName(unsafeModel);
|
|
@@ -1483,6 +1496,17 @@ export const createAdapterFactory =
|
|
|
1483
1496
|
} else {
|
|
1484
1497
|
set = unsafeSet;
|
|
1485
1498
|
}
|
|
1499
|
+
// `transformInput` drops unknown-to-schema and `undefined` fields, so
|
|
1500
|
+
// a `set` that was non-empty on input can resolve to nothing. Re-check
|
|
1501
|
+
// after mapping so this never reaches the adapter as an empty UPDATE.
|
|
1502
|
+
if (
|
|
1503
|
+
Object.keys(increment).length === 0 &&
|
|
1504
|
+
(!set || Object.keys(set).length === 0)
|
|
1505
|
+
) {
|
|
1506
|
+
throw new BetterAuthError(
|
|
1507
|
+
"incrementOne resolved to an empty update: every increment/set field was unknown to the schema or transformed away.",
|
|
1508
|
+
);
|
|
1509
|
+
}
|
|
1486
1510
|
res = await withSpan(
|
|
1487
1511
|
`db incrementOne ${model}`,
|
|
1488
1512
|
{
|
|
@@ -1508,7 +1532,8 @@ export const createAdapterFactory =
|
|
|
1508
1532
|
[ATTR_DB_COLLECTION_NAME]: model,
|
|
1509
1533
|
},
|
|
1510
1534
|
() =>
|
|
1511
|
-
adapter
|
|
1535
|
+
runWithTransaction(adapter, async () => {
|
|
1536
|
+
const trx = await getCurrentAdapter(adapter);
|
|
1512
1537
|
const rows = await trx.findMany<Record<string, any>>({
|
|
1513
1538
|
model: unsafeModel,
|
|
1514
1539
|
where: unsafeWhere,
|
package/src/error/index.ts
CHANGED
|
@@ -11,7 +11,16 @@ export class BetterAuthError extends Error {
|
|
|
11
11
|
|
|
12
12
|
export { type APIErrorCode, BASE_ERROR_CODES } from "./codes";
|
|
13
13
|
|
|
14
|
+
type BaseAPIErrorInstance = InstanceType<typeof BaseAPIError>;
|
|
15
|
+
|
|
14
16
|
export class APIError extends BaseAPIError {
|
|
17
|
+
declare status: BaseAPIErrorInstance["status"];
|
|
18
|
+
declare body: BaseAPIErrorInstance["body"];
|
|
19
|
+
declare headers: BaseAPIErrorInstance["headers"];
|
|
20
|
+
declare statusCode: BaseAPIErrorInstance["statusCode"];
|
|
21
|
+
declare message: string;
|
|
22
|
+
declare errorStack: BaseAPIErrorInstance["errorStack"];
|
|
23
|
+
|
|
15
24
|
constructor(...args: ConstructorParameters<typeof BaseAPIError>) {
|
|
16
25
|
super(...args);
|
|
17
26
|
}
|
|
@@ -1160,9 +1160,13 @@ export type BetterAuthOptions = {
|
|
|
1160
1160
|
*/
|
|
1161
1161
|
storeStateStrategy?: "database" | "cookie";
|
|
1162
1162
|
/**
|
|
1163
|
-
* Store account data after
|
|
1163
|
+
* Store provider account data after an OAuth flow in an encrypted
|
|
1164
|
+
* cookie. This includes OAuth token material such as access tokens,
|
|
1165
|
+
* refresh tokens, ID tokens, scopes, and token expiry.
|
|
1164
1166
|
*
|
|
1165
|
-
* This is useful for database-less
|
|
1167
|
+
* This is useful for database-less flows, but large provider tokens can
|
|
1168
|
+
* still hit browser or proxy cookie/header limits even though Better Auth
|
|
1169
|
+
* chunks oversized account cookies.
|
|
1166
1170
|
*
|
|
1167
1171
|
* @default false
|
|
1168
1172
|
*
|