better-auth 1.7.6 → 1.7.7
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/api/rate-limiter/index.mjs +4 -1
- package/dist/api/routes/sign-in.mjs +2 -1
- package/dist/client/config.mjs +3 -4
- package/dist/crypto/purpose.mjs +19 -0
- package/dist/index.mjs +1 -0
- package/dist/package.mjs +1 -1
- package/dist/plugins/magic-link/index.mjs +23 -4
- package/dist/plugins/oauth-proxy/index.d.mts +5 -6
- package/dist/plugins/oauth-proxy/index.mjs +11 -10
- package/dist/plugins/open-api/index.mjs +1 -0
- package/dist/plugins/organization/client.mjs +2 -1
- package/dist/plugins/phone-number/routes.mjs +1 -0
- package/dist/state.mjs +9 -6
- package/dist/utils/hashing.mjs +1 -1
- package/dist/utils/index.mjs +5 -0
- package/dist/utils/middleware-response.mjs +4 -1
- package/package.json +8 -8
|
@@ -65,7 +65,10 @@ function rateLimitResponse(retryAfter) {
|
|
|
65
65
|
return new Response(JSON.stringify({ message: "Too many requests. Please try again later." }), {
|
|
66
66
|
status: 429,
|
|
67
67
|
statusText: "Too Many Requests",
|
|
68
|
-
headers: {
|
|
68
|
+
headers: {
|
|
69
|
+
"Content-Type": "application/json",
|
|
70
|
+
"X-Retry-After": retryAfter.toString()
|
|
71
|
+
}
|
|
69
72
|
});
|
|
70
73
|
}
|
|
71
74
|
function getRetryAfter(lastRequest, window) {
|
|
@@ -10,6 +10,7 @@ import { generateIdTokenNonce, generateState } from "../../oauth2/state.mjs";
|
|
|
10
10
|
import { safeCloneRequest } from "../../utils/request.mjs";
|
|
11
11
|
import { createEmailVerificationToken } from "./email-verification.mjs";
|
|
12
12
|
import { assertPasswordNotTooLong } from "../../utils/password.mjs";
|
|
13
|
+
import "../../utils/index.mjs";
|
|
13
14
|
import { APIError, BASE_ERROR_CODES } from "@better-auth/core/error";
|
|
14
15
|
import { additionalAuthorizationParamsSchema, supportsIdTokenSignIn, verifyProviderIdToken } from "@better-auth/core/oauth2";
|
|
15
16
|
import { SocialProviderListEnum } from "@better-auth/core/social-providers";
|
|
@@ -193,7 +194,7 @@ const signInSocial = () => createAuthEndpoint("/sign-in/social", {
|
|
|
193
194
|
idToken: token
|
|
194
195
|
},
|
|
195
196
|
callbackURL: c.body.callbackURL,
|
|
196
|
-
disableSignUp: provider.disableImplicitSignUp && !c.body.requestSignUp || provider.disableSignUp,
|
|
197
|
+
disableSignUp: provider.disableImplicitSignUp && !c.body.requestSignUp || provider.options?.disableSignUp || provider.disableSignUp,
|
|
197
198
|
source: {
|
|
198
199
|
method: "oauth",
|
|
199
200
|
oauth: {
|
package/dist/client/config.mjs
CHANGED
|
@@ -19,6 +19,7 @@ const resolvePublicAuthUrl = (basePath) => {
|
|
|
19
19
|
} catch {}
|
|
20
20
|
}
|
|
21
21
|
};
|
|
22
|
+
const matchesSessionSignal = (path) => path === "/sign-out" || path === "/update-user" || path === "/update-session" || path === "/sign-up/email" || path === "/sign-in/email" || path === "/delete-user" || path === "/verify-email" || path === "/revoke-sessions" || path === "/revoke-session" || path === "/revoke-other-sessions" || path === "/change-email" || path === "/change-password";
|
|
22
23
|
const getClientConfig = (options, loadEnv) => {
|
|
23
24
|
const isCredentialsSupported = "credentials" in Request.prototype;
|
|
24
25
|
const baseURL = getBaseURL(options?.baseURL, options?.basePath, void 0, loadEnv) ?? resolvePublicAuthUrl(options?.basePath) ?? "/api/auth";
|
|
@@ -72,9 +73,7 @@ const getClientConfig = (options, loadEnv) => {
|
|
|
72
73
|
};
|
|
73
74
|
const atomListeners = [{
|
|
74
75
|
signal: "$sessionSignal",
|
|
75
|
-
matcher
|
|
76
|
-
return path === "/sign-out" || path === "/update-user" || path === "/update-session" || path === "/sign-up/email" || path === "/sign-in/email" || path === "/delete-user" || path === "/verify-email" || path === "/revoke-sessions" || path === "/revoke-session" || path === "/revoke-other-sessions" || path === "/change-email" || path === "/change-password";
|
|
77
|
-
},
|
|
76
|
+
matcher: matchesSessionSignal,
|
|
78
77
|
callback(path) {
|
|
79
78
|
if (path === "/sign-out") broadcastSessionUpdate("signout");
|
|
80
79
|
else if (path === "/update-user" || path === "/update-session") broadcastSessionUpdate("updateUser");
|
|
@@ -110,4 +109,4 @@ const getClientConfig = (options, loadEnv) => {
|
|
|
110
109
|
};
|
|
111
110
|
};
|
|
112
111
|
//#endregion
|
|
113
|
-
export { getClientConfig };
|
|
112
|
+
export { getClientConfig, matchesSessionSignal };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { hkdf } from "@noble/hashes/hkdf.js";
|
|
2
|
+
import { sha256 } from "@noble/hashes/sha2.js";
|
|
3
|
+
import { bytesToHex, utf8ToBytes } from "@noble/hashes/utils.js";
|
|
4
|
+
//#region src/crypto/purpose.ts
|
|
5
|
+
const salt = utf8ToBytes("better-auth:oauth-encryption:v1");
|
|
6
|
+
function deriveSecret(secret, purpose) {
|
|
7
|
+
return bytesToHex(hkdf(sha256, utf8ToBytes(secret), salt, utf8ToBytes(`better-auth:${purpose}:v1`), 32));
|
|
8
|
+
}
|
|
9
|
+
/** Derive an isolated key for one OAuth ciphertext purpose, retaining rotation versions. */
|
|
10
|
+
function derivePurposeKey(secret, purpose) {
|
|
11
|
+
if (typeof secret === "string") return deriveSecret(secret, purpose);
|
|
12
|
+
return {
|
|
13
|
+
keys: new Map(Array.from(secret.keys, ([version, value]) => [version, deriveSecret(value, purpose)])),
|
|
14
|
+
currentVersion: secret.currentVersion,
|
|
15
|
+
...secret.legacySecret && { legacySecret: deriveSecret(secret.legacySecret, purpose) }
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { derivePurposeKey };
|
package/dist/index.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { getBaseURL, getHost, getHostFromSource, getOrigin, getProtocol, getProt
|
|
|
2
2
|
import { generateGenericState, parseGenericState } from "./state.mjs";
|
|
3
3
|
import { generateIdTokenNonce, generateState, parseState } from "./oauth2/state.mjs";
|
|
4
4
|
import { HIDE_METADATA } from "./utils/hide-metadata.mjs";
|
|
5
|
+
import "./utils/index.mjs";
|
|
5
6
|
import { APIError } from "./api/index.mjs";
|
|
6
7
|
import { betterAuth } from "./auth/full.mjs";
|
|
7
8
|
import { getCurrentAdapter } from "@better-auth/core/context";
|
package/dist/package.mjs
CHANGED
|
@@ -23,6 +23,20 @@ const magicLinkVerifyQuerySchema = z.object({
|
|
|
23
23
|
errorCallbackURL: z.string().meta({ description: "URL to redirect after error." }).optional(),
|
|
24
24
|
newUserCallbackURL: z.string().meta({ description: "URL to redirect after new user signup. Only used if the user is registering for the first time." }).optional()
|
|
25
25
|
});
|
|
26
|
+
const magicLinkRecordSchema = z.object({
|
|
27
|
+
type: z.literal("magic-link"),
|
|
28
|
+
email: z.email(),
|
|
29
|
+
name: z.string().optional()
|
|
30
|
+
}).strict();
|
|
31
|
+
function parseMagicLinkRecord(value) {
|
|
32
|
+
try {
|
|
33
|
+
const parsed = JSON.parse(value);
|
|
34
|
+
return magicLinkRecordSchema.safeParse(parsed);
|
|
35
|
+
} catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const magicLinkIdentifier = (storedToken) => `magic-link:${storedToken}`;
|
|
26
40
|
const magicLink = (options) => {
|
|
27
41
|
const opts = {
|
|
28
42
|
storeToken: "plain",
|
|
@@ -75,8 +89,9 @@ const magicLink = (options) => {
|
|
|
75
89
|
const verificationToken = opts?.generateToken ? await opts.generateToken(email) : generateRandomString(32, "a-z", "A-Z");
|
|
76
90
|
const storedToken = await storeToken(ctx, verificationToken);
|
|
77
91
|
await ctx.context.internalAdapter.createVerificationValue({
|
|
78
|
-
identifier: storedToken,
|
|
92
|
+
identifier: magicLinkIdentifier(storedToken),
|
|
79
93
|
value: JSON.stringify({
|
|
94
|
+
type: "magic-link",
|
|
80
95
|
email,
|
|
81
96
|
name: ctx.body.name
|
|
82
97
|
}),
|
|
@@ -152,10 +167,14 @@ const magicLink = (options) => {
|
|
|
152
167
|
throw ctx.redirect(errorCallbackURL.toString());
|
|
153
168
|
}
|
|
154
169
|
const newUserCallbackURL = new URL(ctx.query.newUserCallbackURL ? decodeURIComponent(ctx.query.newUserCallbackURL) : callbackURL, ctx.context.baseURL).toString();
|
|
155
|
-
const
|
|
156
|
-
const
|
|
170
|
+
const identifier = magicLinkIdentifier(await storeToken(ctx, token));
|
|
171
|
+
const pendingValue = await ctx.context.internalAdapter.findVerificationValue(identifier);
|
|
172
|
+
if (!pendingValue || !parseMagicLinkRecord(pendingValue.value)?.success) redirectWithError("INVALID_TOKEN");
|
|
173
|
+
const tokenValue = await ctx.context.internalAdapter.consumeVerificationValue(identifier);
|
|
157
174
|
if (!tokenValue) redirectWithError("INVALID_TOKEN");
|
|
158
|
-
const
|
|
175
|
+
const record = parseMagicLinkRecord(tokenValue.value);
|
|
176
|
+
if (!record?.success) redirectWithError("INVALID_TOKEN");
|
|
177
|
+
const { email, name } = record.data;
|
|
159
178
|
let isNewUser = false;
|
|
160
179
|
let user = await ctx.context.internalAdapter.findUserByEmail(email).then((res) => res?.user);
|
|
161
180
|
if (!user) if (!opts.disableSignUp) {
|
|
@@ -41,12 +41,11 @@ interface OAuthProxyOptions {
|
|
|
41
41
|
* A dedicated secret used to encrypt and decrypt data passed between
|
|
42
42
|
* servers during the OAuth proxy flow.
|
|
43
43
|
*
|
|
44
|
-
* When set, this secret
|
|
45
|
-
* `BETTER_AUTH_SECRET` for
|
|
46
|
-
* This limits
|
|
47
|
-
* environments (production, preview,
|
|
48
|
-
*
|
|
49
|
-
* protected by the main secret.
|
|
44
|
+
* When set, keys derived from this secret are used **instead of** keys
|
|
45
|
+
* derived from `BETTER_AUTH_SECRET` for OAuth proxy encryption.
|
|
46
|
+
* This limits exposure of data protected only by the main secret if
|
|
47
|
+
* the proxy secret is shared across environments (production, preview,
|
|
48
|
+
* development). A compromised proxy secret can still affect OAuth flows.
|
|
50
49
|
*
|
|
51
50
|
* All environments participating in the OAuth proxy flow must share
|
|
52
51
|
* the same `secret` value.
|
|
@@ -9,7 +9,8 @@ import { redirectOnError } from "../../oauth2/errors.mjs";
|
|
|
9
9
|
import { getOAuthCallbackPath } from "../../oauth2/utils.mjs";
|
|
10
10
|
import { handleOAuthUserInfo, linkOAuthAccount } from "../../oauth2/link-account.mjs";
|
|
11
11
|
import { setOAuthState } from "../../api/state/oauth.mjs";
|
|
12
|
-
import {
|
|
12
|
+
import { derivePurposeKey } from "../../crypto/purpose.mjs";
|
|
13
|
+
import { getAuthStateVerificationIdentifier, parseGenericState } from "../../state.mjs";
|
|
13
14
|
import { PACKAGE_VERSION } from "../../version.mjs";
|
|
14
15
|
import { parseJSON } from "../../client/parser.mjs";
|
|
15
16
|
import { checkSkipProxy, resolveCurrentURL, stripTrailingSlash } from "./utils.mjs";
|
|
@@ -66,7 +67,7 @@ const oauthCallbackQuerySchema = z.object({
|
|
|
66
67
|
});
|
|
67
68
|
const oAuthProxy = (opts) => {
|
|
68
69
|
const maxAge = opts?.maxAge ?? 60;
|
|
69
|
-
const getEncryptionKey = (ctx) => opts?.secret ?? ctx.context.secretConfig;
|
|
70
|
+
const getEncryptionKey = (ctx, purpose) => derivePurposeKey(opts?.secret ?? ctx.context.secretConfig, purpose);
|
|
70
71
|
const oauthProxyCompletion = createAuthEndpoint("/callback/:id/oauth-proxy", {
|
|
71
72
|
method: "GET",
|
|
72
73
|
operationId: "oauthProxyCompletion",
|
|
@@ -84,7 +85,7 @@ const oAuthProxy = (opts) => {
|
|
|
84
85
|
let decryptedPayload;
|
|
85
86
|
try {
|
|
86
87
|
decryptedPayload = await symmetricDecrypt({
|
|
87
|
-
key: getEncryptionKey(ctx),
|
|
88
|
+
key: getEncryptionKey(ctx, "oauth-proxy-profile"),
|
|
88
89
|
data: encryptedProfile
|
|
89
90
|
});
|
|
90
91
|
} catch (e) {
|
|
@@ -225,7 +226,7 @@ const oAuthProxy = (opts) => {
|
|
|
225
226
|
let statePackage;
|
|
226
227
|
try {
|
|
227
228
|
statePackage = parseJSON(await symmetricDecrypt({
|
|
228
|
-
key: getEncryptionKey(ctx),
|
|
229
|
+
key: getEncryptionKey(ctx, "oauth-proxy-package"),
|
|
229
230
|
data: state
|
|
230
231
|
}));
|
|
231
232
|
} catch {
|
|
@@ -245,7 +246,7 @@ const oAuthProxy = (opts) => {
|
|
|
245
246
|
let stateData;
|
|
246
247
|
try {
|
|
247
248
|
stateData = parseJSON(await symmetricDecrypt({
|
|
248
|
-
key: getEncryptionKey(ctx),
|
|
249
|
+
key: getEncryptionKey(ctx, "oauth-proxy-state"),
|
|
249
250
|
data: statePackage.stateCookie
|
|
250
251
|
}));
|
|
251
252
|
} catch (e) {
|
|
@@ -338,7 +339,7 @@ const oAuthProxy = (opts) => {
|
|
|
338
339
|
timestamp: Date.now()
|
|
339
340
|
};
|
|
340
341
|
const encryptedPayload = await symmetricEncrypt({
|
|
341
|
-
key: getEncryptionKey(ctx),
|
|
342
|
+
key: getEncryptionKey(ctx, "oauth-proxy-profile"),
|
|
342
343
|
data: JSON.stringify(payload)
|
|
343
344
|
});
|
|
344
345
|
proxyCallbackURL.searchParams.set("profile", encryptedPayload);
|
|
@@ -366,11 +367,11 @@ const oAuthProxy = (opts) => {
|
|
|
366
367
|
const oauthStateCookie = ctx.context.createAuthCookie("oauth_state");
|
|
367
368
|
const encryptedCookieValue = parseSetCookieHeader(setCookieHeader).get(oauthStateCookie.name)?.value;
|
|
368
369
|
if (encryptedCookieValue) plaintextState = await symmetricDecrypt({
|
|
369
|
-
key: ctx.context.secretConfig,
|
|
370
|
+
key: derivePurposeKey(ctx.context.secretConfig, "oauth-state-cookie"),
|
|
370
371
|
data: encryptedCookieValue
|
|
371
372
|
});
|
|
372
373
|
}
|
|
373
|
-
} else plaintextState = (await ctx.context.internalAdapter.findVerificationValue(originalState))?.value;
|
|
374
|
+
} else plaintextState = (await ctx.context.internalAdapter.findVerificationValue(getAuthStateVerificationIdentifier(originalState)))?.value;
|
|
374
375
|
if (!plaintextState) {
|
|
375
376
|
ctx.context.logger.warn("No OAuth state found for proxy");
|
|
376
377
|
return;
|
|
@@ -378,13 +379,13 @@ const oAuthProxy = (opts) => {
|
|
|
378
379
|
const statePackage = {
|
|
379
380
|
state: originalState,
|
|
380
381
|
stateCookie: await symmetricEncrypt({
|
|
381
|
-
key: getEncryptionKey(ctx),
|
|
382
|
+
key: getEncryptionKey(ctx, "oauth-proxy-state"),
|
|
382
383
|
data: plaintextState
|
|
383
384
|
}),
|
|
384
385
|
isOAuthProxy: true
|
|
385
386
|
};
|
|
386
387
|
const encryptedPackage = await symmetricEncrypt({
|
|
387
|
-
key: getEncryptionKey(ctx),
|
|
388
|
+
key: getEncryptionKey(ctx, "oauth-proxy-package"),
|
|
388
389
|
data: JSON.stringify(statePackage)
|
|
389
390
|
});
|
|
390
391
|
oauthURL.searchParams.set("state", encryptedPackage);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { PACKAGE_VERSION } from "../../version.mjs";
|
|
2
2
|
import { useAuthQuery } from "../../client/query.mjs";
|
|
3
|
+
import { matchesSessionSignal } from "../../client/config.mjs";
|
|
3
4
|
import { adminAc, defaultRoles, memberAc, ownerAc } from "./access/statement.mjs";
|
|
4
5
|
import { ORGANIZATION_ERROR_CODES } from "./error-codes.mjs";
|
|
5
6
|
import { hasPermissionFn } from "./permission.mjs";
|
|
@@ -71,7 +72,7 @@ const organizationClient = (options) => {
|
|
|
71
72
|
},
|
|
72
73
|
{
|
|
73
74
|
matcher(path) {
|
|
74
|
-
return path
|
|
75
|
+
return matchesSessionSignal(path) || path.startsWith("/organization");
|
|
75
76
|
},
|
|
76
77
|
signal: "$activeOrgSignal"
|
|
77
78
|
},
|
|
@@ -5,6 +5,7 @@ import { setSessionCookie } from "../../cookies/index.mjs";
|
|
|
5
5
|
import { getSessionFromCtx } from "../../api/routes/session.mjs";
|
|
6
6
|
import { HIDE_METADATA } from "../../utils/hide-metadata.mjs";
|
|
7
7
|
import { assertPasswordNotTooLong, assertPasswordNotTooShort } from "../../utils/password.mjs";
|
|
8
|
+
import "../../utils/index.mjs";
|
|
8
9
|
import { PHONE_NUMBER_ERROR_CODES } from "./error-codes.mjs";
|
|
9
10
|
import { APIError, BASE_ERROR_CODES } from "@better-auth/core/error";
|
|
10
11
|
import { createAuthEndpoint } from "@better-auth/core/api";
|
package/dist/state.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { generateRandomString } from "./crypto/random.mjs";
|
|
2
2
|
import { symmetricDecrypt, symmetricEncrypt } from "./crypto/index.mjs";
|
|
3
3
|
import { expireCookie } from "./cookies/index.mjs";
|
|
4
|
+
import { derivePurposeKey } from "./crypto/purpose.mjs";
|
|
4
5
|
import { BetterAuthError } from "@better-auth/core/error";
|
|
5
6
|
import * as z from "zod";
|
|
6
7
|
//#region src/state.ts
|
|
@@ -32,6 +33,8 @@ const stateDataSchema = z.looseObject({
|
|
|
32
33
|
*/
|
|
33
34
|
serverContext: z.record(z.string(), z.unknown()).optional()
|
|
34
35
|
});
|
|
36
|
+
/** Verification key for database-backed OAuth and SAML relay state. */
|
|
37
|
+
const getAuthStateVerificationIdentifier = (state) => `auth-state:${state}`;
|
|
35
38
|
const INTERNAL_STATE_KEYS = new Set(Object.keys(stateDataSchema.shape));
|
|
36
39
|
var StateError = class extends BetterAuthError {
|
|
37
40
|
code;
|
|
@@ -59,7 +62,7 @@ async function generateGenericState(c, stateData, settings) {
|
|
|
59
62
|
oauthState: state
|
|
60
63
|
};
|
|
61
64
|
const encryptedData = await symmetricEncrypt({
|
|
62
|
-
key: c.context.secretConfig,
|
|
65
|
+
key: derivePurposeKey(c.context.secretConfig, "oauth-state-cookie"),
|
|
63
66
|
data: JSON.stringify(payload)
|
|
64
67
|
});
|
|
65
68
|
const stateCookie = c.context.createAuthCookie(settings?.cookieName ?? "oauth_state", { maxAge: 600 });
|
|
@@ -78,7 +81,7 @@ async function generateGenericState(c, stateData, settings) {
|
|
|
78
81
|
...stateData,
|
|
79
82
|
oauthState: state
|
|
80
83
|
}),
|
|
81
|
-
identifier: state,
|
|
84
|
+
identifier: getAuthStateVerificationIdentifier(state),
|
|
82
85
|
expiresAt
|
|
83
86
|
})) throw new StateError("Unable to create verification. Make sure the database adapter is properly working and there is a verification table in the database", { code: "state_generation_error" });
|
|
84
87
|
return {
|
|
@@ -99,7 +102,7 @@ async function parseGenericState(c, state, settings) {
|
|
|
99
102
|
});
|
|
100
103
|
try {
|
|
101
104
|
const decryptedData = await symmetricDecrypt({
|
|
102
|
-
key: c.context.secretConfig,
|
|
105
|
+
key: derivePurposeKey(c.context.secretConfig, "oauth-state-cookie"),
|
|
103
106
|
data: encryptedData
|
|
104
107
|
});
|
|
105
108
|
parsedData = stateDataSchema.parse(JSON.parse(decryptedData));
|
|
@@ -117,7 +120,7 @@ async function parseGenericState(c, state, settings) {
|
|
|
117
120
|
});
|
|
118
121
|
expireCookie(c, stateCookie);
|
|
119
122
|
} else {
|
|
120
|
-
const data = await c.context.internalAdapter.findVerificationValue(state);
|
|
123
|
+
const data = await c.context.internalAdapter.findVerificationValue(getAuthStateVerificationIdentifier(state));
|
|
121
124
|
if (!data) throw new StateError("State mismatch: verification not found", {
|
|
122
125
|
code: "state_mismatch",
|
|
123
126
|
details: { state }
|
|
@@ -136,7 +139,7 @@ async function parseGenericState(c, state, settings) {
|
|
|
136
139
|
errorURL: parsedData.errorURL
|
|
137
140
|
});
|
|
138
141
|
expireCookie(c, stateCookie);
|
|
139
|
-
await c.context.internalAdapter.deleteVerificationByIdentifier(state);
|
|
142
|
+
await c.context.internalAdapter.deleteVerificationByIdentifier(getAuthStateVerificationIdentifier(state));
|
|
140
143
|
}
|
|
141
144
|
if (parsedData.expiresAt < Date.now()) throw new StateError("Invalid state: request expired", {
|
|
142
145
|
code: "state_mismatch",
|
|
@@ -146,4 +149,4 @@ async function parseGenericState(c, state, settings) {
|
|
|
146
149
|
return parsedData;
|
|
147
150
|
}
|
|
148
151
|
//#endregion
|
|
149
|
-
export { INTERNAL_STATE_KEYS, StateError, generateGenericState, parseGenericState };
|
|
152
|
+
export { INTERNAL_STATE_KEYS, StateError, generateGenericState, getAuthStateVerificationIdentifier, parseGenericState };
|
package/dist/utils/hashing.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { keccak_256 } from "@noble/hashes/sha3.js";
|
|
2
1
|
import { utf8ToBytes } from "@noble/hashes/utils.js";
|
|
2
|
+
import { keccak_256 } from "@noble/hashes/sha3.js";
|
|
3
3
|
//#region src/utils/hashing.ts
|
|
4
4
|
/**
|
|
5
5
|
* TS implementation of ERC-55 ("Mixed-case checksum address encoding") using @noble/hashes
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
const middlewareResponse = ({ message, status, code }) => ({ response: new Response(JSON.stringify({
|
|
3
3
|
message,
|
|
4
4
|
code
|
|
5
|
-
}), {
|
|
5
|
+
}), {
|
|
6
|
+
status,
|
|
7
|
+
headers: { "Content-Type": "application/json" }
|
|
8
|
+
}) });
|
|
6
9
|
//#endregion
|
|
7
10
|
export { middlewareResponse };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "better-auth",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.7",
|
|
4
4
|
"description": "The most comprehensive authentication framework for TypeScript.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -473,13 +473,13 @@
|
|
|
473
473
|
"kysely": "^0.28.17 || ^0.29.0",
|
|
474
474
|
"nanostores": "^1.3.0",
|
|
475
475
|
"zod": "^4.5.4",
|
|
476
|
-
"@better-auth/core": "1.7.
|
|
477
|
-
"@better-auth/drizzle-adapter": "1.7.
|
|
478
|
-
"@better-auth/kysely-adapter": "1.7.
|
|
479
|
-
"@better-auth/memory-adapter": "1.7.
|
|
480
|
-
"@better-auth/mongo-adapter": "1.7.
|
|
481
|
-
"@better-auth/prisma-adapter": "1.7.
|
|
482
|
-
"@better-auth/telemetry": "1.7.
|
|
476
|
+
"@better-auth/core": "1.7.7",
|
|
477
|
+
"@better-auth/drizzle-adapter": "1.7.7",
|
|
478
|
+
"@better-auth/kysely-adapter": "1.7.7",
|
|
479
|
+
"@better-auth/memory-adapter": "1.7.7",
|
|
480
|
+
"@better-auth/mongo-adapter": "1.7.7",
|
|
481
|
+
"@better-auth/prisma-adapter": "1.7.7",
|
|
482
|
+
"@better-auth/telemetry": "1.7.7"
|
|
483
483
|
},
|
|
484
484
|
"devDependencies": {
|
|
485
485
|
"@lynx-js/react": "^0.121.2",
|