mirror of
https://github.com/LukeHagar/better-auth.git
synced 2025-12-06 12:27:44 +00:00
fix(expo): window.crypto is undefined (#4620)
This commit is contained in:
@@ -698,7 +698,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@better-auth/utils": "0.2.6",
|
"@better-auth/utils": "0.3.0",
|
||||||
"@better-fetch/fetch": "catalog:",
|
"@better-fetch/fetch": "catalog:",
|
||||||
"@noble/ciphers": "^2.0.0",
|
"@noble/ciphers": "^2.0.0",
|
||||||
"@noble/hashes": "^2.0.0",
|
"@noble/hashes": "^2.0.0",
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { constantTimeEqual } from "./buffer";
|
import { constantTimeEqual } from "./buffer";
|
||||||
import { scryptAsync } from "@noble/hashes/scrypt.js";
|
import { scryptAsync } from "@noble/hashes/scrypt.js";
|
||||||
import { getRandomValues } from "@better-auth/utils";
|
|
||||||
import { hex } from "@better-auth/utils/hex";
|
import { hex } from "@better-auth/utils/hex";
|
||||||
import { hexToBytes } from "@noble/hashes/utils.js";
|
import { hexToBytes } from "@noble/hashes/utils.js";
|
||||||
import { BetterAuthError } from "../error";
|
import { BetterAuthError } from "../error";
|
||||||
@@ -23,7 +22,7 @@ async function generateKey(password: string, salt: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const hashPassword = async (password: string) => {
|
export const hashPassword = async (password: string) => {
|
||||||
const salt = hex.encode(getRandomValues(new Uint8Array(16)));
|
const salt = hex.encode(crypto.getRandomValues(new Uint8Array(16)));
|
||||||
const key = await generateKey(password, salt);
|
const key = await generateKey(password, salt);
|
||||||
return `${salt}:${hex.encode(key)}`;
|
return `${salt}:${hex.encode(key)}`;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import type { BetterAuthPlugin, InferOptionSchema } from "../../types/plugins";
|
|||||||
import { generateRandomString } from "../../crypto";
|
import { generateRandomString } from "../../crypto";
|
||||||
import { getSessionFromCtx } from "../../api/routes/session";
|
import { getSessionFromCtx } from "../../api/routes/session";
|
||||||
import { ms, type StringValue as MSStringValue } from "ms";
|
import { ms, type StringValue as MSStringValue } from "ms";
|
||||||
import { getRandomValues } from "@better-auth/utils";
|
|
||||||
import { schema, type DeviceCode } from "./schema";
|
import { schema, type DeviceCode } from "./schema";
|
||||||
import { mergeSchema } from "../../db";
|
import { mergeSchema } from "../../db";
|
||||||
|
|
||||||
@@ -150,7 +149,7 @@ const defaultGenerateDeviceCode = (length: number) => {
|
|||||||
*/
|
*/
|
||||||
const defaultGenerateUserCode = (length: number) => {
|
const defaultGenerateUserCode = (length: number) => {
|
||||||
const chars = new Uint8Array(length);
|
const chars = new Uint8Array(length);
|
||||||
return Array.from(getRandomValues(chars))
|
return Array.from(crypto.getRandomValues(chars))
|
||||||
.map((byte) => defaultCharset[byte % defaultCharset.length])
|
.map((byte) => defaultCharset[byte % defaultCharset.length])
|
||||||
.join("");
|
.join("");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { subtle, getRandomValues } from "@better-auth/utils";
|
import { getWebcryptoSubtle } from "@better-auth/utils";
|
||||||
import { base64 } from "@better-auth/utils/base64";
|
import { base64 } from "@better-auth/utils/base64";
|
||||||
import { joseSecs } from "../../utils/time";
|
import { joseSecs } from "../../utils/time";
|
||||||
import type { JwtOptions, Jwk } from "./types";
|
import type { JwtOptions, Jwk } from "./types";
|
||||||
@@ -31,6 +31,7 @@ export function toExpJWT(
|
|||||||
|
|
||||||
async function deriveKey(secretKey: string): Promise<CryptoKey> {
|
async function deriveKey(secretKey: string): Promise<CryptoKey> {
|
||||||
const enc = new TextEncoder();
|
const enc = new TextEncoder();
|
||||||
|
const subtle = getWebcryptoSubtle();
|
||||||
const keyMaterial = await subtle.importKey(
|
const keyMaterial = await subtle.importKey(
|
||||||
"raw",
|
"raw",
|
||||||
enc.encode(secretKey),
|
enc.encode(secretKey),
|
||||||
@@ -58,10 +59,10 @@ export async function encryptPrivateKey(
|
|||||||
secretKey: string,
|
secretKey: string,
|
||||||
): Promise<{ encryptedPrivateKey: string; iv: string; authTag: string }> {
|
): Promise<{ encryptedPrivateKey: string; iv: string; authTag: string }> {
|
||||||
const key = await deriveKey(secretKey); // Derive a 32-byte key from the provided secret
|
const key = await deriveKey(secretKey); // Derive a 32-byte key from the provided secret
|
||||||
const iv = getRandomValues(new Uint8Array(12)); // 12-byte IV for AES-GCM
|
const iv = crypto.getRandomValues(new Uint8Array(12)); // 12-byte IV for AES-GCM
|
||||||
|
|
||||||
const enc = new TextEncoder();
|
const enc = new TextEncoder();
|
||||||
const ciphertext = await subtle.encrypt(
|
const ciphertext = await getWebcryptoSubtle().encrypt(
|
||||||
{
|
{
|
||||||
name: "AES-GCM",
|
name: "AES-GCM",
|
||||||
iv: iv,
|
iv: iv,
|
||||||
@@ -94,7 +95,7 @@ export async function decryptPrivateKey(
|
|||||||
const ivBuffer = base64.decode(iv);
|
const ivBuffer = base64.decode(iv);
|
||||||
const ciphertext = base64.decode(encryptedPrivateKey);
|
const ciphertext = base64.decode(encryptedPrivateKey);
|
||||||
|
|
||||||
const decrypted = await subtle.decrypt(
|
const decrypted = await getWebcryptoSubtle().decrypt(
|
||||||
{
|
{
|
||||||
name: "AES-GCM",
|
name: "AES-GCM",
|
||||||
iv: ivBuffer as BufferSource,
|
iv: ivBuffer as BufferSource,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { APIError, getSessionFromCtx } from "../../api";
|
|||||||
import { base64 } from "@better-auth/utils/base64";
|
import { base64 } from "@better-auth/utils/base64";
|
||||||
import { generateRandomString } from "../../crypto";
|
import { generateRandomString } from "../../crypto";
|
||||||
import { createHash } from "@better-auth/utils/hash";
|
import { createHash } from "@better-auth/utils/hash";
|
||||||
import { subtle } from "@better-auth/utils";
|
import { getWebcryptoSubtle } from "@better-auth/utils";
|
||||||
import { SignJWT } from "jose";
|
import { SignJWT } from "jose";
|
||||||
import type { BetterAuthOptions, GenericEndpointContext } from "../../types";
|
import type { BetterAuthOptions, GenericEndpointContext } from "../../types";
|
||||||
import { parseSetCookieHeader } from "../../cookies";
|
import { parseSetCookieHeader } from "../../cookies";
|
||||||
@@ -568,7 +568,7 @@ export const mcp = (options: MCPOptions) => {
|
|||||||
}
|
}
|
||||||
let secretKey = {
|
let secretKey = {
|
||||||
alg: "HS256",
|
alg: "HS256",
|
||||||
key: await subtle.generateKey(
|
key: await getWebcryptoSubtle().generateKey(
|
||||||
{
|
{
|
||||||
name: "HMAC",
|
name: "HMAC",
|
||||||
hash: "SHA-256",
|
hash: "SHA-256",
|
||||||
|
|||||||
14
pnpm-lock.yaml
generated
14
pnpm-lock.yaml
generated
@@ -630,8 +630,8 @@ importers:
|
|||||||
packages/better-auth:
|
packages/better-auth:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@better-auth/utils':
|
'@better-auth/utils':
|
||||||
specifier: 0.2.6
|
specifier: 0.3.0
|
||||||
version: 0.2.6
|
version: 0.3.0
|
||||||
'@better-fetch/fetch':
|
'@better-fetch/fetch':
|
||||||
specifier: 'catalog:'
|
specifier: 'catalog:'
|
||||||
version: 1.1.18
|
version: 1.1.18
|
||||||
@@ -1623,8 +1623,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==}
|
resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
'@better-auth/utils@0.2.6':
|
'@better-auth/utils@0.3.0':
|
||||||
resolution: {integrity: sha512-3y/vaL5Ox33dBwgJ6ub3OPkVqr6B5xL2kgxNHG8eHZuryLyG/4JSPGqjbdRSgjuy9kALUZYDFl+ORIAxlWMSuA==}
|
resolution: {integrity: sha512-W+Adw6ZA6mgvnSnhOki270rwJ42t4XzSK6YWGF//BbVXL6SwCLWfyzBc1lN2m/4RM28KubdBKQ4X5VMoLRNPQw==}
|
||||||
|
|
||||||
'@better-fetch/fetch@1.1.18':
|
'@better-fetch/fetch@1.1.18':
|
||||||
resolution: {integrity: sha512-rEFOE1MYIsBmoMJtQbl32PGHHXuG2hDxvEd7rUHE0vCBoFQVSDqaVs9hkZEtHCxRoY+CljXKFCOuJ8uxqw1LcA==}
|
resolution: {integrity: sha512-rEFOE1MYIsBmoMJtQbl32PGHHXuG2hDxvEd7rUHE0vCBoFQVSDqaVs9hkZEtHCxRoY+CljXKFCOuJ8uxqw1LcA==}
|
||||||
@@ -13053,9 +13053,7 @@ snapshots:
|
|||||||
'@babel/helper-string-parser': 7.27.1
|
'@babel/helper-string-parser': 7.27.1
|
||||||
'@babel/helper-validator-identifier': 7.27.1
|
'@babel/helper-validator-identifier': 7.27.1
|
||||||
|
|
||||||
'@better-auth/utils@0.2.6':
|
'@better-auth/utils@0.3.0': {}
|
||||||
dependencies:
|
|
||||||
uncrypto: 0.1.3
|
|
||||||
|
|
||||||
'@better-fetch/fetch@1.1.18': {}
|
'@better-fetch/fetch@1.1.18': {}
|
||||||
|
|
||||||
@@ -15876,7 +15874,9 @@ snapshots:
|
|||||||
metro-runtime: 0.83.1
|
metro-runtime: 0.83.1
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@babel/core'
|
- '@babel/core'
|
||||||
|
- bufferutil
|
||||||
- supports-color
|
- supports-color
|
||||||
|
- utf-8-validate
|
||||||
|
|
||||||
'@react-native/normalize-colors@0.79.5': {}
|
'@react-native/normalize-colors@0.79.5': {}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user