@better-auth/electron 1.7.0-beta.0 → 1.7.0-beta.10
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-D6xRwPM0.d.mts → client-D5QKMJbp.d.mts} +13 -17
- package/dist/client.d.mts +1 -1
- package/dist/client.mjs +28 -42
- package/dist/index.d.mts +1 -7
- package/dist/index.mjs +10 -33
- package/dist/preload.d.mts +795 -97
- package/dist/preload.mjs +1 -1
- package/dist/proxy.d.mts +1 -1
- package/dist/proxy.mjs +1 -1
- package/dist/storage.d.mts +1 -1
- package/dist/{version-CzfTSPRz.mjs → version-C-W6yUfI.mjs} +1 -1
- package/package.json +10 -10
|
@@ -35,13 +35,6 @@ interface ElectronOptions extends ElectronSharedOptions {
|
|
|
35
35
|
* @default "better-auth"
|
|
36
36
|
*/
|
|
37
37
|
cookiePrefix?: string | undefined;
|
|
38
|
-
/**
|
|
39
|
-
* Override the origin for Electron API routes.
|
|
40
|
-
* Enable this if you're facing cors origin issues with Electron API routes.
|
|
41
|
-
*
|
|
42
|
-
* @default false
|
|
43
|
-
*/
|
|
44
|
-
disableOriginOverride?: boolean | undefined;
|
|
45
38
|
}
|
|
46
39
|
//#endregion
|
|
47
40
|
//#region src/preload.d.ts
|
|
@@ -248,6 +241,7 @@ declare const requestAuthOptionsSchema: z.ZodObject<{
|
|
|
248
241
|
disableRedirect: z.ZodOptional<z.ZodBoolean>;
|
|
249
242
|
scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
250
243
|
requestSignUp: z.ZodOptional<z.ZodBoolean>;
|
|
244
|
+
additionalParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
251
245
|
additionalData: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
252
246
|
}, z.core.$strip>;
|
|
253
247
|
type ElectronRequestAuthOptions = z.infer<typeof requestAuthOptionsSchema>;
|
|
@@ -323,11 +317,6 @@ declare const electronClient: <O extends ElectronClientOptions>(options: O) => {
|
|
|
323
317
|
mode?: RequestMode | undefined;
|
|
324
318
|
cache?: RequestCache | undefined;
|
|
325
319
|
credentials?: RequestCredentials | undefined;
|
|
326
|
-
headers?: (HeadersInit & (HeadersInit | {
|
|
327
|
-
accept: "application/json" | "text/plain" | "application/octet-stream";
|
|
328
|
-
"content-type": "application/json" | "text/plain" | "application/x-www-form-urlencoded" | "multipart/form-data" | "application/octet-stream";
|
|
329
|
-
authorization: "Bearer" | "Basic";
|
|
330
|
-
})) | undefined;
|
|
331
320
|
integrity?: string | undefined;
|
|
332
321
|
keepalive?: boolean | undefined;
|
|
333
322
|
method?: string | undefined;
|
|
@@ -361,6 +350,12 @@ declare const electronClient: <O extends ElectronClientOptions>(options: O) => {
|
|
|
361
350
|
prefix: string | (() => string | undefined) | undefined;
|
|
362
351
|
value: string | (() => string | undefined) | undefined;
|
|
363
352
|
}) | undefined;
|
|
353
|
+
headers?: {} | {
|
|
354
|
+
[x: string]: string | undefined;
|
|
355
|
+
accept?: ((string & {}) | "application/json" | "text/plain" | "application/octet-stream") | undefined;
|
|
356
|
+
"content-type"?: ((string & {}) | "application/x-www-form-urlencoded" | "application/json" | "text/plain" | "multipart/form-data" | "application/octet-stream") | undefined;
|
|
357
|
+
authorization?: ((string & {}) | `Bearer ${string}` | `Basic ${string}`) | undefined;
|
|
358
|
+
} | undefined;
|
|
364
359
|
body?: any;
|
|
365
360
|
query?: any;
|
|
366
361
|
params?: any;
|
|
@@ -378,11 +373,6 @@ declare const electronClient: <O extends ElectronClientOptions>(options: O) => {
|
|
|
378
373
|
mode?: RequestMode | undefined;
|
|
379
374
|
cache?: RequestCache | undefined;
|
|
380
375
|
credentials?: RequestCredentials | undefined;
|
|
381
|
-
headers?: (HeadersInit & (HeadersInit | {
|
|
382
|
-
accept: "application/json" | "text/plain" | "application/octet-stream";
|
|
383
|
-
"content-type": "application/json" | "text/plain" | "application/x-www-form-urlencoded" | "multipart/form-data" | "application/octet-stream";
|
|
384
|
-
authorization: "Bearer" | "Basic";
|
|
385
|
-
})) | undefined;
|
|
386
376
|
integrity?: string | undefined;
|
|
387
377
|
keepalive?: boolean | undefined;
|
|
388
378
|
method?: string | undefined;
|
|
@@ -416,6 +406,12 @@ declare const electronClient: <O extends ElectronClientOptions>(options: O) => {
|
|
|
416
406
|
prefix: string | (() => string | undefined) | undefined;
|
|
417
407
|
value: string | (() => string | undefined) | undefined;
|
|
418
408
|
}) | undefined;
|
|
409
|
+
headers?: {} | {
|
|
410
|
+
[x: string]: string | undefined;
|
|
411
|
+
accept?: ((string & {}) | "application/json" | "text/plain" | "application/octet-stream") | undefined;
|
|
412
|
+
"content-type"?: ((string & {}) | "application/x-www-form-urlencoded" | "application/json" | "text/plain" | "multipart/form-data" | "application/octet-stream") | undefined;
|
|
413
|
+
authorization?: ((string & {}) | `Bearer ${string}` | `Basic ${string}`) | undefined;
|
|
414
|
+
} | undefined;
|
|
419
415
|
body?: any;
|
|
420
416
|
query?: any;
|
|
421
417
|
params?: any;
|
package/dist/client.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as setupRenderer, a as authenticate, c as ElectronClientOptions, d as Storage, f as FetchUserImageResult, g as SetupRendererConfig, h as ExposedBridges, i as ElectronRequestAuthOptions, l as ElectronProxyClientOptions, m as normalizeUserOutput, n as handleDeepLink, o as kElectron, p as fetchUserImage, r as ElectronAuthenticateOptions, s as requestAuth, t as electronClient, u as ElectronSharedClientOptions, y as ElectronSharedOptions } from "./client-
|
|
1
|
+
import { _ as setupRenderer, a as authenticate, c as ElectronClientOptions, d as Storage, f as FetchUserImageResult, g as SetupRendererConfig, h as ExposedBridges, i as ElectronRequestAuthOptions, l as ElectronProxyClientOptions, m as normalizeUserOutput, n as handleDeepLink, o as kElectron, p as fetchUserImage, r as ElectronAuthenticateOptions, s as requestAuth, t as electronClient, u as ElectronSharedClientOptions, y as ElectronSharedOptions } from "./client-D5QKMJbp.mjs";
|
|
2
2
|
export { ElectronAuthenticateOptions, ElectronClientOptions, ElectronProxyClientOptions, ElectronRequestAuthOptions, ElectronSharedClientOptions, ElectronSharedOptions, ExposedBridges, FetchUserImageResult, SetupRendererConfig, Storage, authenticate, electronClient, fetchUserImage, handleDeepLink, kElectron, normalizeUserOutput, requestAuth, setupRenderer };
|
package/dist/client.mjs
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import { t as PACKAGE_VERSION } from "./version-
|
|
1
|
+
import { t as PACKAGE_VERSION } from "./version-C-W6yUfI.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";
|
|
5
5
|
import { APIError as APIError$1, getBaseURL, isDevelopment, isTest, safeJSONParse } from "better-auth";
|
|
6
6
|
import { generateRandomString } from "better-auth/crypto";
|
|
7
7
|
import * as z from "zod";
|
|
8
|
-
import { Buffer } from "node:buffer";
|
|
9
|
-
import { createHash } from "@better-auth/utils/hash";
|
|
10
8
|
import { signInSocial } from "better-auth/api";
|
|
11
|
-
import { parseSetCookieHeader } from "better-auth/cookies";
|
|
9
|
+
import { cookieNameRegex, parseSetCookieHeader } from "better-auth/cookies";
|
|
10
|
+
import { generateCodeChallenge } from "better-auth/oauth2";
|
|
11
|
+
import { Buffer } from "node:buffer";
|
|
12
12
|
import electron, { shell } from "electron";
|
|
13
13
|
import { isDevelopment as isDevelopment$1 } from "@better-auth/core/env";
|
|
14
|
+
import { isPublicRoutableHost } from "@better-auth/core/utils/host";
|
|
14
15
|
import { resolve } from "node:path";
|
|
15
16
|
//#region src/user.ts
|
|
16
17
|
const { net } = electron;
|
|
@@ -37,7 +38,7 @@ async function fetchUserImage(baseURL, url, options) {
|
|
|
37
38
|
parsed = new URL(relative, base);
|
|
38
39
|
}
|
|
39
40
|
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return null;
|
|
40
|
-
if (!isDevelopment$1() &&
|
|
41
|
+
if (!isDevelopment$1() && !isPublicRoutableHost(parsed.hostname)) return null;
|
|
41
42
|
resolvedUrl = parsed.href;
|
|
42
43
|
} catch {
|
|
43
44
|
return null;
|
|
@@ -116,25 +117,6 @@ async function decodeDataImageUrl(url, options) {
|
|
|
116
117
|
return null;
|
|
117
118
|
}
|
|
118
119
|
}
|
|
119
|
-
function isLocalOrigin(parsed) {
|
|
120
|
-
const hostname = parsed.hostname.toLowerCase();
|
|
121
|
-
if (hostname === "localhost") return true;
|
|
122
|
-
const m = hostname.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);
|
|
123
|
-
if (m) {
|
|
124
|
-
const a = Number(m[1]);
|
|
125
|
-
const b = Number(m[2]);
|
|
126
|
-
if (a === 127) return true;
|
|
127
|
-
if (a === 10) return true;
|
|
128
|
-
if (a === 172 && b >= 16 && b <= 31) return true;
|
|
129
|
-
if (a === 192 && b === 168) return true;
|
|
130
|
-
if (a === 169 && b === 254) return true;
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
const h = hostname.replace(/^\[|\]$/g, "");
|
|
134
|
-
if (h === "::1" || /^(0:){7}1$/.test(h) || h === "0:0:0:0:0:0:0:1") return true;
|
|
135
|
-
if (/^fe[89ab][0-9a-f]/i.test(h)) return true;
|
|
136
|
-
return false;
|
|
137
|
-
}
|
|
138
120
|
function detectImageType(bytes) {
|
|
139
121
|
if (bytes.length < 12) return null;
|
|
140
122
|
if (bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71 && bytes[4] === 13 && bytes[5] === 10 && bytes[6] === 26 && bytes[7] === 10) return "image/png";
|
|
@@ -168,8 +150,8 @@ async function requestAuth(clientOptions, options, cfg) {
|
|
|
168
150
|
if (!isProcessType("browser")) throw new BetterAuthError("`requestAuth` can only be called in the main process");
|
|
169
151
|
const { randomBytes } = await import("node:crypto");
|
|
170
152
|
const state = generateRandomString(16, "A-Z", "a-z", "0-9");
|
|
171
|
-
const codeVerifier = base64Url.encode(randomBytes(32));
|
|
172
|
-
const codeChallenge =
|
|
153
|
+
const codeVerifier = base64Url.encode(randomBytes(32), { padding: false });
|
|
154
|
+
const codeChallenge = await generateCodeChallenge(codeVerifier);
|
|
173
155
|
(globalThis[kElectron] ??= /* @__PURE__ */ new Map()).set(state, codeVerifier);
|
|
174
156
|
let url = null;
|
|
175
157
|
if (cfg?.provider) {
|
|
@@ -186,7 +168,6 @@ async function requestAuth(clientOptions, options, cfg) {
|
|
|
186
168
|
} else url = new URL(options.signInURL);
|
|
187
169
|
url.searchParams.set("client_id", options.clientID || "electron");
|
|
188
170
|
url.searchParams.set("code_challenge", codeChallenge);
|
|
189
|
-
url.searchParams.set("code_challenge_method", "S256");
|
|
190
171
|
url.searchParams.set("state", state);
|
|
191
172
|
await shell.openExternal(url.toString(), { activate: true });
|
|
192
173
|
}
|
|
@@ -492,10 +473,13 @@ function getCookie(cookie) {
|
|
|
492
473
|
try {
|
|
493
474
|
parsed = JSON.parse(cookie);
|
|
494
475
|
} catch (_e) {}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
476
|
+
const pairs = [];
|
|
477
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
478
|
+
if (value.expires && new Date(value.expires) < /* @__PURE__ */ new Date()) continue;
|
|
479
|
+
if (!cookieNameRegex.test(key)) continue;
|
|
480
|
+
pairs.push(`${key}=${encodeURIComponent(value.value)}`);
|
|
481
|
+
}
|
|
482
|
+
return pairs.join("; ");
|
|
499
483
|
}
|
|
500
484
|
/**
|
|
501
485
|
* Compare if session cookies have actually changed by comparing their values.
|
|
@@ -594,6 +578,16 @@ const electronClient = (options) => {
|
|
|
594
578
|
const cookieName = `${opts.storagePrefix}.cookie`;
|
|
595
579
|
const localCacheName = `${opts.storagePrefix}.local_cache`;
|
|
596
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
|
+
};
|
|
597
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`.");
|
|
598
592
|
return {
|
|
599
593
|
id: "electron",
|
|
@@ -607,22 +601,13 @@ const electronClient = (options) => {
|
|
|
607
601
|
options ||= {};
|
|
608
602
|
options.credentials = "omit";
|
|
609
603
|
options.headers = {
|
|
604
|
+
origin: `${scheme}:/`,
|
|
610
605
|
...options.headers,
|
|
611
606
|
cookie,
|
|
612
607
|
"user-agent": app.userAgentFallback,
|
|
613
|
-
"electron-origin": `${scheme}:/`,
|
|
614
608
|
"x-skip-oauth-proxy": "true"
|
|
615
609
|
};
|
|
616
|
-
if (url.endsWith("/sign-out"))
|
|
617
|
-
setEncrypted(cookieName, "{}");
|
|
618
|
-
store?.atoms.session?.set({
|
|
619
|
-
...store.atoms.session.get(),
|
|
620
|
-
data: null,
|
|
621
|
-
error: null,
|
|
622
|
-
isPending: false
|
|
623
|
-
});
|
|
624
|
-
setEncrypted(localCacheName, "{}");
|
|
625
|
-
}
|
|
610
|
+
if (url.endsWith("/sign-out")) clearSessionCache();
|
|
626
611
|
return {
|
|
627
612
|
url,
|
|
628
613
|
options
|
|
@@ -645,6 +630,7 @@ const electronClient = (options) => {
|
|
|
645
630
|
const data = context.data;
|
|
646
631
|
setEncrypted(localCacheName, JSON.stringify(data));
|
|
647
632
|
}
|
|
633
|
+
if (context.request.url.toString().includes("/sign-out")) clearSessionCache();
|
|
648
634
|
},
|
|
649
635
|
onError: async (context) => {
|
|
650
636
|
webContents.getFocusedWebContents()?.send(`${getChannelPrefixWithDelimiter(opts.channelPrefix)}error`, {
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as FetchUserImageResult, m as normalizeUserOutput, p as fetchUserImage, v as ElectronOptions, y as ElectronSharedOptions } from "./client-
|
|
1
|
+
import { f as FetchUserImageResult, m as normalizeUserOutput, p as fetchUserImage, v as ElectronOptions, y as ElectronSharedOptions } from "./client-D5QKMJbp.mjs";
|
|
2
2
|
import * as better_auth0 from "better-auth";
|
|
3
3
|
import * as z from "zod";
|
|
4
4
|
import * as _better_auth_core0 from "@better-auth/core";
|
|
@@ -16,9 +16,6 @@ declare module "@better-auth/core" {
|
|
|
16
16
|
declare const electron: (options?: ElectronOptions | undefined) => {
|
|
17
17
|
id: "electron";
|
|
18
18
|
version: string;
|
|
19
|
-
onRequest(request: Request, _ctx: better_auth0.AuthContext): Promise<{
|
|
20
|
-
request: Request;
|
|
21
|
-
} | undefined>;
|
|
22
19
|
hooks: {
|
|
23
20
|
after: ({
|
|
24
21
|
matcher: (ctx: HookEndpointContext) => boolean;
|
|
@@ -205,7 +202,6 @@ declare const electron: (options?: ElectronOptions | undefined) => {
|
|
|
205
202
|
provider: z.ZodString;
|
|
206
203
|
state: z.ZodString;
|
|
207
204
|
code_challenge: z.ZodString;
|
|
208
|
-
code_challenge_method: z.ZodOptional<z.ZodString>;
|
|
209
205
|
}, z.core.$strip>;
|
|
210
206
|
metadata: {
|
|
211
207
|
scope: "http";
|
|
@@ -255,7 +251,6 @@ declare const electron: (options?: ElectronOptions | undefined) => {
|
|
|
255
251
|
client_id: z.ZodString;
|
|
256
252
|
state: z.ZodString;
|
|
257
253
|
code_challenge: z.ZodString;
|
|
258
|
-
code_challenge_method: z.ZodOptional<z.ZodString>;
|
|
259
254
|
}, z.core.$strip>;
|
|
260
255
|
body: z.ZodObject<{
|
|
261
256
|
callbackURL: z.ZodOptional<z.ZodString>;
|
|
@@ -325,7 +320,6 @@ declare const electron: (options?: ElectronOptions | undefined) => {
|
|
|
325
320
|
codeExpiresIn: number;
|
|
326
321
|
redirectCookieExpiresIn: number;
|
|
327
322
|
cookiePrefix: string;
|
|
328
|
-
disableOriginOverride?: boolean | undefined;
|
|
329
323
|
clientID: string;
|
|
330
324
|
};
|
|
331
325
|
$ERROR_CODES: {
|
package/dist/index.mjs
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
import { t as PACKAGE_VERSION } from "./version-
|
|
1
|
+
import { t as PACKAGE_VERSION } from "./version-C-W6yUfI.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";
|
|
5
5
|
import { defineErrorCodes, safeJSONParse } from "better-auth";
|
|
6
6
|
import { generateRandomString } from "better-auth/crypto";
|
|
7
7
|
import * as z from "zod";
|
|
8
|
-
import { Buffer } from "node:buffer";
|
|
9
|
-
import { timingSafeEqual } from "node:crypto";
|
|
10
|
-
import { SocialProviderListEnum } from "@better-auth/core/social-providers";
|
|
11
8
|
import { safeJSONParse as safeJSONParse$1 } from "@better-auth/core/utils/json";
|
|
12
|
-
import { createHash } from "@better-auth/utils/hash";
|
|
13
9
|
import { betterFetch } from "@better-fetch/fetch";
|
|
14
10
|
import { createAuthEndpoint, sessionMiddleware } from "better-auth/api";
|
|
15
11
|
import { setSessionCookie } from "better-auth/cookies";
|
|
16
12
|
import { parseUserOutput } from "better-auth/db";
|
|
13
|
+
import { generateCodeChallenge } from "better-auth/oauth2";
|
|
17
14
|
//#region src/error-codes.ts
|
|
18
15
|
const ELECTRON_ERROR_CODES = defineErrorCodes({
|
|
19
16
|
INVALID_CLIENT_ID: "Invalid client ID",
|
|
@@ -56,18 +53,13 @@ const electronToken = (_opts) => createAuthEndpoint("/electron/token", {
|
|
|
56
53
|
}
|
|
57
54
|
}
|
|
58
55
|
}, async (ctx) => {
|
|
59
|
-
const token = await ctx.context.internalAdapter.
|
|
60
|
-
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);
|
|
61
58
|
const tokenRecord = safeJSONParse$1(token.value);
|
|
62
59
|
if (!tokenRecord) throw APIError.from("INTERNAL_SERVER_ERROR", ELECTRON_ERROR_CODES.INVALID_TOKEN);
|
|
63
60
|
if (tokenRecord.state !== ctx.body.state) throw APIError.from("BAD_REQUEST", ELECTRON_ERROR_CODES.STATE_MISMATCH);
|
|
64
61
|
if (!tokenRecord.codeChallenge) throw APIError.from("BAD_REQUEST", ELECTRON_ERROR_CODES.MISSING_CODE_CHALLENGE);
|
|
65
|
-
if (tokenRecord.
|
|
66
|
-
const codeChallenge = Buffer.from(base64Url.decode(tokenRecord.codeChallenge));
|
|
67
|
-
const codeVerifier = Buffer.from(await createHash("SHA-256").digest(ctx.body.code_verifier));
|
|
68
|
-
if (codeChallenge.length !== codeVerifier.length || !timingSafeEqual(codeChallenge, codeVerifier)) throw APIError.from("BAD_REQUEST", ELECTRON_ERROR_CODES.INVALID_CODE_VERIFIER);
|
|
69
|
-
} else if (tokenRecord.codeChallenge !== ctx.body.code_verifier) throw APIError.from("BAD_REQUEST", ELECTRON_ERROR_CODES.INVALID_CODE_VERIFIER);
|
|
70
|
-
await ctx.context.internalAdapter.deleteVerificationByIdentifier(`electron:${ctx.body.token}`);
|
|
62
|
+
if (await generateCodeChallenge(ctx.body.code_verifier) !== tokenRecord.codeChallenge) throw APIError.from("BAD_REQUEST", ELECTRON_ERROR_CODES.INVALID_CODE_VERIFIER);
|
|
71
63
|
const user = await ctx.context.internalAdapter.findUserById(tokenRecord.userId);
|
|
72
64
|
if (!user) throw APIError.from("INTERNAL_SERVER_ERROR", BASE_ERROR_CODES.USER_NOT_FOUND);
|
|
73
65
|
const session = await ctx.context.internalAdapter.createSession(user.id);
|
|
@@ -84,8 +76,7 @@ const electronToken = (_opts) => createAuthEndpoint("/electron/token", {
|
|
|
84
76
|
const electronInitOAuthProxyQuerySchema = z.object({
|
|
85
77
|
provider: z.string().nonempty(),
|
|
86
78
|
state: z.string(),
|
|
87
|
-
code_challenge: z.string()
|
|
88
|
-
code_challenge_method: z.string().optional()
|
|
79
|
+
code_challenge: z.string()
|
|
89
80
|
});
|
|
90
81
|
const electronInitOAuthProxy = (opts) => createAuthEndpoint("/electron/init-oauth-proxy", {
|
|
91
82
|
method: "GET",
|
|
@@ -117,17 +108,14 @@ const electronInitOAuthProxy = (opts) => createAuthEndpoint("/electron/init-oaut
|
|
|
117
108
|
}
|
|
118
109
|
}
|
|
119
110
|
}, async (ctx) => {
|
|
120
|
-
const isSocialProvider = SocialProviderListEnum.safeParse(ctx.query.provider);
|
|
121
|
-
if (!isSocialProvider && !ctx.context.getPlugin("generic-oauth")) throw APIError.from("BAD_REQUEST", BASE_ERROR_CODES.PROVIDER_NOT_FOUND);
|
|
122
111
|
const headers = new Headers(ctx.request?.headers);
|
|
123
112
|
headers.set("origin", new URL(ctx.context.baseURL).origin);
|
|
124
113
|
let setCookie = null;
|
|
125
114
|
const searchParams = new URLSearchParams();
|
|
126
115
|
searchParams.set("client_id", opts.clientID || "electron");
|
|
127
116
|
searchParams.set("code_challenge", ctx.query.code_challenge);
|
|
128
|
-
searchParams.set("code_challenge_method", ctx.query.code_challenge_method || "plain");
|
|
129
117
|
searchParams.set("state", ctx.query.state);
|
|
130
|
-
const res = await betterFetch(
|
|
118
|
+
const res = await betterFetch(`/sign-in/social?${searchParams.toString()}`, {
|
|
131
119
|
baseURL: ctx.context.baseURL,
|
|
132
120
|
method: "POST",
|
|
133
121
|
body: { provider: ctx.query.provider },
|
|
@@ -148,8 +136,7 @@ const electronInitOAuthProxy = (opts) => createAuthEndpoint("/electron/init-oaut
|
|
|
148
136
|
const electronTransferUserQuerySchema = z.object({
|
|
149
137
|
client_id: z.string(),
|
|
150
138
|
state: z.string(),
|
|
151
|
-
code_challenge: z.string()
|
|
152
|
-
code_challenge_method: z.string().optional()
|
|
139
|
+
code_challenge: z.string()
|
|
153
140
|
});
|
|
154
141
|
const electronTransferUserBodySchema = z.object({ callbackURL: z.string().optional() });
|
|
155
142
|
const electronTransferUser = (_opts, { handleTransfer }) => createAuthEndpoint("/electron/transfer-user", {
|
|
@@ -201,10 +188,10 @@ const electron = (options) => {
|
|
|
201
188
|
...options || {}
|
|
202
189
|
};
|
|
203
190
|
const hookMatcher = (ctx) => {
|
|
204
|
-
return !!(ctx.path?.startsWith("/sign-in") || ctx.path?.startsWith("/sign-up") || ctx.path?.startsWith("/callback") || ctx.path?.startsWith("/
|
|
191
|
+
return !!(ctx.path?.startsWith("/sign-in") || ctx.path?.startsWith("/sign-up") || ctx.path?.startsWith("/callback") || ctx.path?.startsWith("/magic-link/verify") || ctx.path?.startsWith("/email-otp/verify-email") || ctx.path?.startsWith("/verify-email") || ctx.path?.startsWith("/one-tap/callback") || ctx.path?.startsWith("/passkey/verify-authentication") || ctx.path?.startsWith("/phone-number/verify"));
|
|
205
192
|
};
|
|
206
193
|
const handleTransfer = async (ctx, payload) => {
|
|
207
|
-
const { client_id, state, code_challenge
|
|
194
|
+
const { client_id, state, code_challenge } = payload;
|
|
208
195
|
const userId = ctx.context.session?.user.id || ctx.context.newSession?.user.id;
|
|
209
196
|
if (!userId || client_id !== opts.clientID) return null;
|
|
210
197
|
if (!state) throw APIError.from("BAD_REQUEST", ELECTRON_ERROR_CODES.MISSING_STATE);
|
|
@@ -218,7 +205,6 @@ const electron = (options) => {
|
|
|
218
205
|
value: JSON.stringify({
|
|
219
206
|
userId,
|
|
220
207
|
codeChallenge: code_challenge,
|
|
221
|
-
codeChallengeMethod: code_challenge_method.toLowerCase(),
|
|
222
208
|
state
|
|
223
209
|
}),
|
|
224
210
|
expiresAt
|
|
@@ -237,14 +223,6 @@ const electron = (options) => {
|
|
|
237
223
|
return {
|
|
238
224
|
id: "electron",
|
|
239
225
|
version: PACKAGE_VERSION,
|
|
240
|
-
async onRequest(request, _ctx) {
|
|
241
|
-
if (opts.disableOriginOverride || request.headers.get("origin")) return;
|
|
242
|
-
const electronOrigin = request.headers.get("electron-origin");
|
|
243
|
-
if (!electronOrigin) return;
|
|
244
|
-
const req = request.clone();
|
|
245
|
-
req.headers.set("origin", electronOrigin);
|
|
246
|
-
return { request: req };
|
|
247
|
-
},
|
|
248
226
|
hooks: { after: [{
|
|
249
227
|
matcher: (ctx) => !hookMatcher(ctx),
|
|
250
228
|
handler: createAuthMiddleware(async (ctx) => {
|
|
@@ -259,7 +237,6 @@ const electron = (options) => {
|
|
|
259
237
|
const querySchema = z.object({
|
|
260
238
|
client_id: z.string(),
|
|
261
239
|
code_challenge: z.string().nonempty(),
|
|
262
|
-
code_challenge_method: z.string().optional().default("plain"),
|
|
263
240
|
state: z.string().nonempty()
|
|
264
241
|
});
|
|
265
242
|
const cookie = ctx.context.createAuthCookie("transfer_token", { maxAge: opts.codeExpiresIn });
|