@better-auth/electron 1.7.0-beta.5 → 1.7.0-beta.6
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.mjs +13 -11
- package/dist/index.mjs +3 -4
- package/dist/preload.d.mts +128 -22
- package/dist/proxy.mjs +1 -1
- package/dist/{version-DzWb5tB_.mjs → version-BTlyLl-N.mjs} +1 -1
- package/package.json +7 -7
package/dist/client.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as PACKAGE_VERSION } from "./version-
|
|
1
|
+
import { t as PACKAGE_VERSION } from "./version-BTlyLl-N.mjs";
|
|
2
2
|
import { n as isProcessType, r as parseProtocolScheme, t as getChannelPrefixWithDelimiter } from "./utils-DxDKRT6e.mjs";
|
|
3
3
|
import { BetterAuthError } from "@better-auth/core/error";
|
|
4
4
|
import { base64, base64Url } from "@better-auth/utils/base64";
|
|
@@ -578,6 +578,16 @@ const electronClient = (options) => {
|
|
|
578
578
|
const cookieName = `${opts.storagePrefix}.cookie`;
|
|
579
579
|
const localCacheName = `${opts.storagePrefix}.local_cache`;
|
|
580
580
|
const { getDecrypted, setEncrypted } = storageAdapter(opts.storage, new Set([cookieName, localCacheName]));
|
|
581
|
+
const clearSessionCache = () => {
|
|
582
|
+
setEncrypted(cookieName, "{}");
|
|
583
|
+
store?.atoms.session?.set({
|
|
584
|
+
...store.atoms.session.get(),
|
|
585
|
+
data: null,
|
|
586
|
+
error: null,
|
|
587
|
+
isPending: false
|
|
588
|
+
});
|
|
589
|
+
setEncrypted(localCacheName, "{}");
|
|
590
|
+
};
|
|
581
591
|
if ((isDevelopment() || isTest()) && /^(?!\.)(?!.*\.\.)(?!.*\.$)[^.]+\.[^.]+$/.test(scheme)) console.warn("The provided scheme does not follow the reverse domain name notation. For example: `app.example.com` -> `com.example.app`.");
|
|
582
592
|
return {
|
|
583
593
|
id: "electron",
|
|
@@ -597,16 +607,7 @@ const electronClient = (options) => {
|
|
|
597
607
|
"user-agent": app.userAgentFallback,
|
|
598
608
|
"x-skip-oauth-proxy": "true"
|
|
599
609
|
};
|
|
600
|
-
if (url.endsWith("/sign-out"))
|
|
601
|
-
setEncrypted(cookieName, "{}");
|
|
602
|
-
store?.atoms.session?.set({
|
|
603
|
-
...store.atoms.session.get(),
|
|
604
|
-
data: null,
|
|
605
|
-
error: null,
|
|
606
|
-
isPending: false
|
|
607
|
-
});
|
|
608
|
-
setEncrypted(localCacheName, "{}");
|
|
609
|
-
}
|
|
610
|
+
if (url.endsWith("/sign-out")) clearSessionCache();
|
|
610
611
|
return {
|
|
611
612
|
url,
|
|
612
613
|
options
|
|
@@ -629,6 +630,7 @@ const electronClient = (options) => {
|
|
|
629
630
|
const data = context.data;
|
|
630
631
|
setEncrypted(localCacheName, JSON.stringify(data));
|
|
631
632
|
}
|
|
633
|
+
if (context.request.url.toString().includes("/sign-out")) clearSessionCache();
|
|
632
634
|
},
|
|
633
635
|
onError: async (context) => {
|
|
634
636
|
webContents.getFocusedWebContents()?.send(`${getChannelPrefixWithDelimiter(opts.channelPrefix)}error`, {
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as PACKAGE_VERSION } from "./version-
|
|
1
|
+
import { t as PACKAGE_VERSION } from "./version-BTlyLl-N.mjs";
|
|
2
2
|
import { createAuthMiddleware } from "@better-auth/core/api";
|
|
3
3
|
import { APIError, BASE_ERROR_CODES } from "@better-auth/core/error";
|
|
4
4
|
import { base64Url } from "@better-auth/utils/base64";
|
|
@@ -53,14 +53,13 @@ const electronToken = (_opts) => createAuthEndpoint("/electron/token", {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
}, async (ctx) => {
|
|
56
|
-
const token = await ctx.context.internalAdapter.
|
|
57
|
-
if (!token
|
|
56
|
+
const token = await ctx.context.internalAdapter.consumeVerificationValue(`electron:${ctx.body.token}`);
|
|
57
|
+
if (!token) throw APIError.from("NOT_FOUND", ELECTRON_ERROR_CODES.INVALID_TOKEN);
|
|
58
58
|
const tokenRecord = safeJSONParse$1(token.value);
|
|
59
59
|
if (!tokenRecord) throw APIError.from("INTERNAL_SERVER_ERROR", ELECTRON_ERROR_CODES.INVALID_TOKEN);
|
|
60
60
|
if (tokenRecord.state !== ctx.body.state) throw APIError.from("BAD_REQUEST", ELECTRON_ERROR_CODES.STATE_MISMATCH);
|
|
61
61
|
if (!tokenRecord.codeChallenge) throw APIError.from("BAD_REQUEST", ELECTRON_ERROR_CODES.MISSING_CODE_CHALLENGE);
|
|
62
62
|
if (await generateCodeChallenge(ctx.body.code_verifier) !== tokenRecord.codeChallenge) throw APIError.from("BAD_REQUEST", ELECTRON_ERROR_CODES.INVALID_CODE_VERIFIER);
|
|
63
|
-
await ctx.context.internalAdapter.deleteVerificationByIdentifier(`electron:${ctx.body.token}`);
|
|
64
63
|
const user = await ctx.context.internalAdapter.findUserById(tokenRecord.userId);
|
|
65
64
|
if (!user) throw APIError.from("INTERNAL_SERVER_ERROR", BASE_ERROR_CODES.USER_NOT_FOUND);
|
|
66
65
|
const session = await ctx.context.internalAdapter.createSession(user.id);
|
package/dist/preload.d.mts
CHANGED
|
@@ -33,6 +33,7 @@ type DBAdapterDebugLogOption = boolean | {
|
|
|
33
33
|
delete?: boolean | undefined;
|
|
34
34
|
deleteMany?: boolean | undefined;
|
|
35
35
|
consumeOne?: boolean | undefined;
|
|
36
|
+
incrementOne?: boolean | undefined;
|
|
36
37
|
count?: boolean | undefined;
|
|
37
38
|
} | {
|
|
38
39
|
/**
|
|
@@ -208,7 +209,7 @@ interface DBAdapterFactoryConfig<Options extends BetterAuthOptions = BetterAuthO
|
|
|
208
209
|
/**
|
|
209
210
|
* The action which was called from the adapter.
|
|
210
211
|
*/
|
|
211
|
-
action: "create" | "update" | "findOne" | "findMany" | "updateMany" | "delete" | "deleteMany" | "consumeOne" | "count";
|
|
212
|
+
action: "create" | "update" | "findOne" | "findMany" | "updateMany" | "delete" | "deleteMany" | "consumeOne" | "incrementOne" | "count";
|
|
212
213
|
/**
|
|
213
214
|
* The model name.
|
|
214
215
|
*/
|
|
@@ -437,15 +438,43 @@ type DBAdapter<Options extends BetterAuthOptions = BetterAuthOptions> = {
|
|
|
437
438
|
* race-safe primitive for consuming single-use credentials
|
|
438
439
|
* (verification tokens, authorization codes, one-time tokens).
|
|
439
440
|
*
|
|
440
|
-
* Always defined on the factory-wrapped adapter.
|
|
441
|
-
* `CustomAdapter`
|
|
442
|
-
*
|
|
443
|
-
* and returns the row only when the delete reports an affected row.
|
|
441
|
+
* Always defined on the factory-wrapped adapter. The underlying
|
|
442
|
+
* `CustomAdapter` must implement this natively; there is no portable
|
|
443
|
+
* fallback that can guarantee cross-process single-use semantics.
|
|
444
444
|
*/
|
|
445
445
|
consumeOne: <T>(data: {
|
|
446
446
|
model: string;
|
|
447
447
|
where: Where[];
|
|
448
448
|
}) => Promise<T | null>;
|
|
449
|
+
/**
|
|
450
|
+
* Atomically apply signed numeric deltas to a single row matching the where
|
|
451
|
+
* clause. For each entry in `increment`, the operation applies
|
|
452
|
+
* `field = field + delta` in one atomic step; a negative delta decrements.
|
|
453
|
+
*
|
|
454
|
+
* The `where` clause is both the selector AND the guard: comparison
|
|
455
|
+
* operators are honored, so passing `{ field: "remaining", operator: "gt",
|
|
456
|
+
* value: 0 }` only mutates the row while `remaining` is still above zero.
|
|
457
|
+
* When the guard matches no row, the operation makes no change and returns
|
|
458
|
+
* `null`.
|
|
459
|
+
*
|
|
460
|
+
* The optional `set` map assigns absolute values to fields in the same
|
|
461
|
+
* atomic operation, alongside the increments.
|
|
462
|
+
*
|
|
463
|
+
* Returns the updated row, or `null` when the guard matched no row. Under
|
|
464
|
+
* concurrent invocation against the same row, this is the race-safe
|
|
465
|
+
* primitive for guarded counter updates (e.g. decrementing a remaining-uses
|
|
466
|
+
* counter only while it is still positive).
|
|
467
|
+
*
|
|
468
|
+
* Always defined on the factory-wrapped adapter. The underlying
|
|
469
|
+
* `CustomAdapter` must implement this natively; there is no portable
|
|
470
|
+
* fallback that can guarantee guarded counter semantics across runtimes.
|
|
471
|
+
*/
|
|
472
|
+
incrementOne: <T>(data: {
|
|
473
|
+
model: string;
|
|
474
|
+
where: Where[];
|
|
475
|
+
increment: Record<string, number>;
|
|
476
|
+
set?: Record<string, unknown> | undefined;
|
|
477
|
+
}) => Promise<T | null>;
|
|
449
478
|
/**
|
|
450
479
|
* Execute multiple operations in a transaction.
|
|
451
480
|
* If the adapter doesn't support transactions, operations will be executed sequentially.
|
|
@@ -528,18 +557,33 @@ interface CustomAdapter {
|
|
|
528
557
|
where: CleanedWhere[];
|
|
529
558
|
}) => Promise<number>;
|
|
530
559
|
/**
|
|
531
|
-
*
|
|
532
|
-
* factory falls back to `transaction(findMany + deleteMany)`.
|
|
560
|
+
* Native atomic single-row consume.
|
|
533
561
|
* Implementing this method natively (e.g. `DELETE ... RETURNING *`,
|
|
534
562
|
* `findOneAndDelete`, `OUTPUT deleted.*`) gives one round trip and the
|
|
535
563
|
* strongest race-safety guarantee. Implementations must delete at most
|
|
536
|
-
* one matching row.
|
|
537
|
-
* next minor on `next`.
|
|
564
|
+
* one matching row.
|
|
538
565
|
*/
|
|
539
|
-
consumeOne
|
|
566
|
+
consumeOne: <T>(data: {
|
|
540
567
|
model: string;
|
|
541
568
|
where: CleanedWhere[];
|
|
542
569
|
}) => Promise<T | null>;
|
|
570
|
+
/**
|
|
571
|
+
* Native atomic guarded counter mutation. Applies
|
|
572
|
+
* `field = field + delta` for each entry in `increment` (negative deltas
|
|
573
|
+
* decrement), with `where` acting as both selector and guard and `set`
|
|
574
|
+
* assigning absolute values in the same operation. Returns the updated row,
|
|
575
|
+
* or `null` when the guard matched no row.
|
|
576
|
+
*
|
|
577
|
+
* Implementing this natively (e.g. `UPDATE ... SET n = n + $delta WHERE ...
|
|
578
|
+
* RETURNING *`) gives one round trip and the strongest race-safety
|
|
579
|
+
* guarantee.
|
|
580
|
+
*/
|
|
581
|
+
incrementOne: <T>(data: {
|
|
582
|
+
model: string;
|
|
583
|
+
where: CleanedWhere[];
|
|
584
|
+
increment: Record<string, number>;
|
|
585
|
+
set?: Record<string, unknown> | undefined;
|
|
586
|
+
}) => Promise<T | null>;
|
|
543
587
|
count: ({
|
|
544
588
|
model,
|
|
545
589
|
where
|
|
@@ -577,7 +621,6 @@ type BaseRateLimit = z.infer<typeof rateLimitSchema>;
|
|
|
577
621
|
/**
|
|
578
622
|
* Rate limit schema type used by better-auth for rate limiting
|
|
579
623
|
*/
|
|
580
|
-
type RateLimit<DBOptions extends BetterAuthOptions["rateLimit"] = BetterAuthOptions["rateLimit"], Plugins extends BetterAuthOptions["plugins"] = BetterAuthOptions["plugins"]> = Prettify$1<BaseRateLimit & InferDBFieldsFromOptions<DBOptions> & InferDBFieldsFromPlugins<"rateLimit", Plugins>>; //#endregion
|
|
581
624
|
//#endregion
|
|
582
625
|
//#region ../core/dist/db/schema/session.d.mts
|
|
583
626
|
//#region src/db/schema/session.d.ts
|
|
@@ -2783,6 +2826,7 @@ declare const socialProviders: {
|
|
|
2783
2826
|
audience: string | string[];
|
|
2784
2827
|
maxTokenAge: string;
|
|
2785
2828
|
issuer: string | undefined;
|
|
2829
|
+
verifyClaims: (claims: Record<string, unknown>) => boolean;
|
|
2786
2830
|
};
|
|
2787
2831
|
getUserInfo(token: OAuth2Tokens & {
|
|
2788
2832
|
user?: {
|
|
@@ -5368,6 +5412,23 @@ interface InternalAdapter<_Options extends BetterAuthOptions = BetterAuthOptions
|
|
|
5368
5412
|
* pair at single-use credential consumption sites.
|
|
5369
5413
|
*/
|
|
5370
5414
|
consumeVerificationValue(identifier: string): Promise<Verification | null>;
|
|
5415
|
+
/**
|
|
5416
|
+
* First-writer-wins create keyed by a deterministic primary key derived from
|
|
5417
|
+
* `identifier`. Returns `true` when this caller created the row and `false`
|
|
5418
|
+
* when a row for the same identifier already existed.
|
|
5419
|
+
*
|
|
5420
|
+
* The dual of `consumeVerificationValue`: reserve races to create a marker
|
|
5421
|
+
* exactly once, where consume races to delete one exactly once. Use it for
|
|
5422
|
+
* replay tombstones (a SAML assertion id, a JWT `jti`) where the first caller
|
|
5423
|
+
* wins. The database path is atomic via the primary key. Secondary-storage-only
|
|
5424
|
+
* verification is not supported for reservation and runtime implementations
|
|
5425
|
+
* should fail closed unless verification is backed by the database.
|
|
5426
|
+
*/
|
|
5427
|
+
reserveVerificationValue(data: {
|
|
5428
|
+
identifier: string;
|
|
5429
|
+
value: string;
|
|
5430
|
+
expiresAt: Date;
|
|
5431
|
+
}): Promise<boolean>;
|
|
5371
5432
|
updateVerificationByIdentifier(identifier: string, data: Partial<Verification>): Promise<Verification>;
|
|
5372
5433
|
refreshUserSessions(user: User): Promise<void>;
|
|
5373
5434
|
}
|
|
@@ -5919,8 +5980,30 @@ type DynamicBaseURLConfig = {
|
|
|
5919
5980
|
*/
|
|
5920
5981
|
type BaseURLConfig = string | DynamicBaseURLConfig;
|
|
5921
5982
|
interface BetterAuthRateLimitStorage {
|
|
5922
|
-
|
|
5923
|
-
|
|
5983
|
+
/**
|
|
5984
|
+
* Atomically records one request against `key` within the rolling `window`
|
|
5985
|
+
* (in seconds) and reports whether it is allowed.
|
|
5986
|
+
*
|
|
5987
|
+
* When `allowed` is true the count was incremented within the active window,
|
|
5988
|
+
* or the window had elapsed and was reset to start at 1. When `allowed` is
|
|
5989
|
+
* false the limit was already reached and `retryAfter` is the number of
|
|
5990
|
+
* seconds until the window frees up.
|
|
5991
|
+
*
|
|
5992
|
+
* Performing the check and the increment in a single step closes the
|
|
5993
|
+
* concurrent-bypass gap of the separate `get`/`set` path: N simultaneous
|
|
5994
|
+
* requests can no longer all pass a stale read before any increment lands.
|
|
5995
|
+
*
|
|
5996
|
+
* Custom storages must implement this operation directly. Better Auth no
|
|
5997
|
+
* longer accepts separate `get`/`set` rate-limit storage because that shape
|
|
5998
|
+
* cannot enforce a distributed limit under concurrent requests.
|
|
5999
|
+
*/
|
|
6000
|
+
consume: (key: string, rule: {
|
|
6001
|
+
window: number;
|
|
6002
|
+
max: number;
|
|
6003
|
+
}) => Promise<{
|
|
6004
|
+
allowed: boolean;
|
|
6005
|
+
retryAfter: number | null;
|
|
6006
|
+
}>;
|
|
5924
6007
|
}
|
|
5925
6008
|
type BetterAuthRateLimitRule = {
|
|
5926
6009
|
/**
|
|
@@ -6702,6 +6785,20 @@ type BetterAuthOptions = {
|
|
|
6702
6785
|
* @default "compact"
|
|
6703
6786
|
*/
|
|
6704
6787
|
strategy?: "compact" | "jwt" | "jwe";
|
|
6788
|
+
/**
|
|
6789
|
+
* JWT-specific configuration for `strategy: "jwt"`.
|
|
6790
|
+
*/
|
|
6791
|
+
jwt?: {
|
|
6792
|
+
/**
|
|
6793
|
+
* Which signing key is used for cookie-cache JWTs.
|
|
6794
|
+
*
|
|
6795
|
+
* - `"secret"`: uses the Better Auth secret with HS256.
|
|
6796
|
+
* - `"jwt-plugin"`: uses the installed `jwt()` plugin's asymmetric signing keys.
|
|
6797
|
+
*
|
|
6798
|
+
* @default "secret"
|
|
6799
|
+
*/
|
|
6800
|
+
signingKey?: "secret" | "jwt-plugin";
|
|
6801
|
+
};
|
|
6705
6802
|
/**
|
|
6706
6803
|
* Controls stateless cookie cache refresh behavior.
|
|
6707
6804
|
*
|
|
@@ -6881,9 +6978,13 @@ type BetterAuthOptions = {
|
|
|
6881
6978
|
*/
|
|
6882
6979
|
storeStateStrategy?: "database" | "cookie";
|
|
6883
6980
|
/**
|
|
6884
|
-
* Store account data after
|
|
6981
|
+
* Store provider account data after an OAuth flow in an encrypted
|
|
6982
|
+
* cookie. This includes OAuth token material such as access tokens,
|
|
6983
|
+
* refresh tokens, ID tokens, scopes, and token expiry.
|
|
6885
6984
|
*
|
|
6886
|
-
* This is useful for database-less
|
|
6985
|
+
* This is useful for database-less flows, but large provider tokens can
|
|
6986
|
+
* still hit browser or proxy cookie/header limits even though Better Auth
|
|
6987
|
+
* chunks oversized account cookies.
|
|
6887
6988
|
*
|
|
6888
6989
|
* @default false
|
|
6889
6990
|
*
|
|
@@ -7388,16 +7489,21 @@ interface SecondaryStorage {
|
|
|
7388
7489
|
get: (key: string) => Awaitable<unknown>;
|
|
7389
7490
|
/**
|
|
7390
7491
|
* Atomically get a value and delete it from storage.
|
|
7492
|
+
*/
|
|
7493
|
+
getAndDelete: (key: string) => Awaitable<unknown>;
|
|
7494
|
+
/**
|
|
7495
|
+
* Atomically increment the counter at `key` by one, returning the
|
|
7496
|
+
* post-increment value.
|
|
7391
7497
|
*
|
|
7392
|
-
*
|
|
7393
|
-
*
|
|
7394
|
-
*
|
|
7498
|
+
* When the key is absent, it is created with a value of `1` and the given
|
|
7499
|
+
* `ttl` (in SECONDS). The TTL is applied only on creation; later increments
|
|
7500
|
+
* never extend it, so the counter expires a fixed window after it was first
|
|
7501
|
+
* created.
|
|
7395
7502
|
*
|
|
7396
|
-
*
|
|
7397
|
-
*
|
|
7398
|
-
* security-sensitive consume paths.
|
|
7503
|
+
* Required so secondary-storage-backed rate limiting can enforce the limit
|
|
7504
|
+
* in one distributed-safe operation.
|
|
7399
7505
|
*/
|
|
7400
|
-
|
|
7506
|
+
increment: (key: string, ttl: number) => Awaitable<number>;
|
|
7401
7507
|
set: (
|
|
7402
7508
|
/**
|
|
7403
7509
|
* Key to store
|
package/dist/proxy.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as PACKAGE_VERSION } from "./version-
|
|
1
|
+
import { t as PACKAGE_VERSION } from "./version-BTlyLl-N.mjs";
|
|
2
2
|
import { r as parseProtocolScheme } from "./utils-DxDKRT6e.mjs";
|
|
3
3
|
import { parseCookies } from "better-auth/cookies";
|
|
4
4
|
//#region src/proxy.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-auth/electron",
|
|
3
|
-
"version": "1.7.0-beta.
|
|
3
|
+
"version": "1.7.0-beta.6",
|
|
4
4
|
"description": "Better Auth integration for Electron applications.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -80,17 +80,17 @@
|
|
|
80
80
|
"better-sqlite3": "^12.6.2",
|
|
81
81
|
"electron": "^41.2.2",
|
|
82
82
|
"tsdown": "0.21.1",
|
|
83
|
-
"@better-auth/core": "1.7.0-beta.
|
|
84
|
-
"better-auth": "1.7.0-beta.
|
|
83
|
+
"@better-auth/core": "1.7.0-beta.6",
|
|
84
|
+
"better-auth": "1.7.0-beta.6"
|
|
85
85
|
},
|
|
86
86
|
"peerDependencies": {
|
|
87
|
-
"@better-auth/utils": "0.4.
|
|
88
|
-
"@better-fetch/fetch": "1.
|
|
87
|
+
"@better-auth/utils": "0.4.2",
|
|
88
|
+
"@better-fetch/fetch": "1.3.1",
|
|
89
89
|
"better-call": "1.3.6",
|
|
90
90
|
"conf": "^15.0.2",
|
|
91
91
|
"electron": ">=36.0.0",
|
|
92
|
-
"@better-auth/core": "^1.7.0-beta.
|
|
93
|
-
"better-auth": "^1.7.0-beta.
|
|
92
|
+
"@better-auth/core": "^1.7.0-beta.6",
|
|
93
|
+
"better-auth": "^1.7.0-beta.6"
|
|
94
94
|
},
|
|
95
95
|
"peerDependenciesMeta": {
|
|
96
96
|
"electron": {
|