@iskra-bun/auth-kit 0.1.0 → 0.2.0
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/CHANGELOG.md +49 -0
- package/README.md +1 -1
- package/dist/index.d.ts +103 -19
- package/dist/index.js +103 -37
- package/dist/index.js.map +1 -1
- package/package.json +7 -4
- package/src/better-auth-config.ts +207 -72
- package/src/index.ts +7 -3
- package/src/schema.ts +140 -120
- package/src/types.ts +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,54 @@
|
|
|
1
1
|
# @iskra-bun/auth-kit
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 76028ab: **Breaking (0.x):** `createBetterAuth` no longer defaults `baseURL` to `http://localhost:3000` everywhere. It now reads `BETTER_AUTH_URL` when `baseURL` is not passed (the hardcoded default overrode better-auth's own fallback to it), keeps the localhost default only outside production, and with `NODE_ENV=production` throws when neither is set or when the origin is plain `http://` on a host other than `localhost`, `127.0.0.1` or `[::1]`. better-auth marks the session cookies `Secure` only for an https `baseURL` and trusts that origin, so a production app built without one sent its session cookies over plain HTTP and trusted `http://localhost:3000`. Pass `baseURL: 'https://your-app.example.com'` (or set `BETTER_AUTH_URL`) in production. The rule is exported as `resolveAuthBaseURL(baseURL?, who?)`, which web-kit's `AuthFeature` now uses (its behaviour is unchanged).
|
|
8
|
+
- 7720bd5: New `rateLimit: false` and `ipAddressHeaders` options for better-auth's rate limiter and client IP. The MySQL `verification.value` column is `text` (OAuth state is longer than 255 characters, so OIDC sign-in failed in strict mode); existing tables need `ALTER TABLE verification MODIFY value TEXT NOT NULL`.
|
|
9
|
+
- cb3ec43: **Breaking (types):** `User` and `SignUpInput` custom fields are `unknown` (were `any`), and `socialProviders` takes better-auth's own option type. The OIDC profile mapping (`mapOidcProfile`, now exported and tested) returns only local user fields: the `id` it returned was ignored by better-auth, which takes the account's identity from the verified `sub`.
|
|
10
|
+
- 0f1ce5b: **Security:** authorization fixes.
|
|
11
|
+
|
|
12
|
+
- `ApiKeyFeature`: an `Authorization: Bearer` token that is not a valid API key no longer returns 401 for every request (it broke JWT/session auth app-wide, public routes included); `requireApiKey()`/`requireScope()` still reject it with the validation error. Cache hits now re-check expiry and ignore keys removed from the config (a Redis cache outlives the restart that rotated them). The `onError`, `onValidated` and `customExtractor` / `"custom"` strategy options are now honored.
|
|
13
|
+
- `PermissionsFeature`: role permissions were pushed into the array returned by `loadPermissions()`; a loader returning a shared/cached array leaked them (including admin `"*"`) to other users. The array is now copied.
|
|
14
|
+
- `AuthFeature` (**breaking**): email/password login is only enabled in `authMode: "email"` (previously hardcoded on, so OIDC deployments still exposed an open `/sign-up/email`); opt back in with the new `enableEmailPassword` option. `enableSelfRegistration: false` is now honored and disables sign-up.
|
|
15
|
+
- `auth-kit`: new `disableSignUp` option for `createBetterAuth`.
|
|
16
|
+
|
|
17
|
+
- ef2009b: **Security:** update dependencies with known vulnerabilities (`bun audit` went from 67 findings, 1 critical and 38 high, to one accepted dev-only finding).
|
|
18
|
+
|
|
19
|
+
- `better-auth` ^1.6.33 (account takeover via pre-account hijacking), `hono` ^4.12.34, `ajv` ^8.20.0, `mysql2` ^3.24.4 (web-kit, auth-kit, db-kit).
|
|
20
|
+
- `drizzle-orm` ^0.45.2 (SQL injection via improperly escaped identifiers). **db-kit moves from 0.30 to 0.45**, the same line web-kit and auth-kit already used, so schemas are shared across kits again; `drizzle-kit` ^0.31.11 now matches it (0.30 exited with "requires newer version of drizzle-orm", so migrations never ran), and `@libsql/client` ^0.18.0 satisfies drizzle's peer range.
|
|
21
|
+
- `c12` ^3.3.4 in core (drops the vulnerable `tar` 6 pulled in through `giget` 1).
|
|
22
|
+
- `nodemailer` ^10.0.10 in mailer-kit (arbitrary file read / SSRF via the raw option, SMTP command and header injection).
|
|
23
|
+
|
|
24
|
+
- f2346f5: **Breaking behavior:** production safeguards now apply unless `NODE_ENV` is `development` or `test`. They applied only to `NODE_ENV=production` exactly, so a deploy that forgot it (or used `staging`) sent session cookies without `Secure`, accepted sample secrets and plain-http auth URLs, honored `disableCSRFCheck` and wrote pretty logs. `NODE_ENV` is also read when the app runs: `bun build` replaced a literal `process.env.NODE_ENV` with `"development"` when it was unset while building, so a compiled binary ignored the value it ran with. `app.start()` logs a warning when `NODE_ENV` is unset. Set `NODE_ENV=development` for local development; the templates' `bun dev` scripts do. New `nodeEnv()`, `isProductionEnv()` and `isDevelopmentEnv()` in `@iskra-bun/core`.
|
|
25
|
+
- c24201a: **Security (breaking):** with `NODE_ENV=production`, `createBetterAuth` refuses a secret that is still a sample value: one containing `change-me`, `dev-secret`, `dev-only`, `your-secret` or `placeholder`, compared without case, `-`, `_`, `.` or spaces (so `changeme` and `CHANGE_ME` count too). A sample secret copied from docs or an `.env.example` is public, and it signs better-auth's session cookie cache, which is trusted without a database lookup: anyone could forge a session for any user. The error names the matching word, never the secret.
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- d6151cb: `oidcConfig.mapping` is now applied: `email`, `name`, `image` and `emailVerified` name the claims the user's fields are read from, falling back to the standard claims when the profile lacks them (a mapped `emailVerified` claim counts as verified when it is `true` or `"true"`). A mapped email is verified only by its paired mapped flag, or by the standard `email_verified` when it is the same address, so a verified standard email never vouches for a different mapped one (better-auth links verified emails to existing local users). It was accepted but never read, so a provider with non-standard claim names created users without them. `mapOidcProfile(profile, mapping?)` takes the mapping as an optional second argument. `jwksEndpoint`, `mapping.id` and `mapping.extraFields` are marked `@deprecated` and still ignored: better-auth takes the JWKS only from the discovery document's `jwks_uri`, the account's identity always comes from the verified `sub`, and extra user fields need better-auth `user.additionalFields`.
|
|
30
|
+
- 093656f: `oidcConfig` endpoints that are not set now come from the issuer's discovery document. They defaulted to Keycloak's `${issuer}/protocol/openid-connect/{auth,token,userinfo}` paths, and better-auth only fills the endpoints left unset from discovery, so every other provider (Auth0, Okta, Entra ID, …) got URLs that do not exist and sign-in failed unless all three were configured by hand. `authorizationEndpoint`, `tokenEndpoint` and `userinfoEndpoint` still override the discovered ones. The provider config is built by the new exported `oidcProviderConfig(oidcConfig)`; web-kit's `AuthFeature` passes its `oidcConfig` through, so it gets the same behaviour. With only the `issuer` set, the provider now depends on discovery at startup: if the discovery document cannot be fetched then (for example the IdP container starts after the app), better-auth logs the error and leaves the provider out until the app restarts. Set the three endpoints explicitly to avoid that dependency.
|
|
31
|
+
- 840439a: Packages declare the runtime they are tested on: `engines.bun` `>=1.3.0` (the monorepo now builds and tests on Bun 1.3). `create-iskra`, a CLI that also runs under `npm create iskra`, declares `engines.node` `>=18`.
|
|
32
|
+
|
|
33
|
+
Every package is published with an npm provenance attestation (`publishConfig.provenance`), linking each version to the commit and CI run that built it.
|
|
34
|
+
|
|
35
|
+
- 8f31aa5: **Security:** `createBetterAuth` pins `advanced.disableOriginCheck: false`. Left unset, better-auth skips its Origin check (CSRF on cookie-authenticated requests) and its `callbackURL`/`redirectTo` validation (open redirects) whenever it believes it runs under test: `NODE_ENV=test`, or any `TEST` environment variable other than `"false"` (`TEST=0` included), which a production image can carry from its build.
|
|
36
|
+
- Updated dependencies [620da18]
|
|
37
|
+
- Updated dependencies [b635a2c]
|
|
38
|
+
- Updated dependencies [5b2b0fd]
|
|
39
|
+
- Updated dependencies [58d4a8f]
|
|
40
|
+
- Updated dependencies [5c70c5b]
|
|
41
|
+
- Updated dependencies [ec198d4]
|
|
42
|
+
- Updated dependencies [cb3ec43]
|
|
43
|
+
- Updated dependencies [ef2009b]
|
|
44
|
+
- Updated dependencies [840439a]
|
|
45
|
+
- Updated dependencies [dbf8817]
|
|
46
|
+
- Updated dependencies [3dc5581]
|
|
47
|
+
- Updated dependencies [9872d30]
|
|
48
|
+
- Updated dependencies [f2346f5]
|
|
49
|
+
- Updated dependencies [3579944]
|
|
50
|
+
- @iskra-bun/core@0.2.0
|
|
51
|
+
|
|
3
52
|
## 0.1.0
|
|
4
53
|
|
|
5
54
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ El esquema Drizzle (`pgSchema`, `mysqlSchema`, `sqliteSchema`) y los tipos (`Use
|
|
|
28
28
|
|
|
29
29
|
## Documentacion
|
|
30
30
|
|
|
31
|
-
Guia completa: [
|
|
31
|
+
Guia completa: [@iskra-bun/auth-kit](https://iskra-docs.fly.dev/es/packages/auth-kit/)
|
|
32
32
|
|
|
33
33
|
## Licencia
|
|
34
34
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Auth as Auth$1 } from 'better-auth';
|
|
1
|
+
import { BetterAuthOptions, Auth as Auth$1 } from 'better-auth';
|
|
2
|
+
import { GenericOAuthUserInfo } from 'better-auth/plugins/generic-oauth';
|
|
2
3
|
import * as drizzle_orm_pg_core from 'drizzle-orm/pg-core';
|
|
3
4
|
import { PgDatabase, PgQueryResultHKT } from 'drizzle-orm/pg-core';
|
|
4
5
|
import * as drizzle_orm_mysql_core from 'drizzle-orm/mysql-core';
|
|
@@ -12,15 +13,30 @@ import { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core';
|
|
|
12
13
|
* Drizzle instance rather than `any` leaking into callers. The dialect-core base
|
|
13
14
|
* classes are part of `drizzle-orm` itself, so no driver dependency is required.
|
|
14
15
|
*/
|
|
15
|
-
type AuthKitDrizzleDb = PgDatabase<PgQueryResultHKT, Record<string, unknown>> | MySqlDatabase<MySqlQueryResultHKT, PreparedQueryHKTBase, Record<string, unknown>> | BaseSQLiteDatabase<
|
|
16
|
+
type AuthKitDrizzleDb = PgDatabase<PgQueryResultHKT, Record<string, unknown>> | MySqlDatabase<MySqlQueryResultHKT, PreparedQueryHKTBase, Record<string, unknown>> | BaseSQLiteDatabase<'sync' | 'async', unknown, Record<string, unknown>>;
|
|
17
|
+
/**
|
|
18
|
+
* The origin better-auth runs on: `baseURL`, else `BETTER_AUTH_URL`, else
|
|
19
|
+
* `http://localhost:3000` outside production. It decides the cookies'
|
|
20
|
+
* `Secure` flag and is a trusted origin, so production requires one and it
|
|
21
|
+
* must be https (plain http only for localhost, 127.0.0.1 and [::1]). `who`
|
|
22
|
+
* prefixes the error messages.
|
|
23
|
+
*/
|
|
24
|
+
declare function resolveAuthBaseURL(baseURL?: string, who?: string): string;
|
|
16
25
|
interface BetterAuthConfigOptions {
|
|
17
26
|
db: AuthKitDrizzleDb;
|
|
18
|
-
adapterType:
|
|
27
|
+
adapterType: 'postgres' | 'mysql' | 'sqlite';
|
|
19
28
|
secret: string;
|
|
29
|
+
/**
|
|
30
|
+
* The app's public origin. Defaults to `BETTER_AUTH_URL`, then (outside
|
|
31
|
+
* production only) `http://localhost:3000`; must be https in production
|
|
32
|
+
* unless it is localhost. See `resolveAuthBaseURL`.
|
|
33
|
+
*/
|
|
20
34
|
baseURL?: string;
|
|
21
35
|
basePath?: string;
|
|
22
36
|
trustedOrigins?: string[];
|
|
23
37
|
enableEmailPassword?: boolean;
|
|
38
|
+
/** Reject `/sign-up/email` (accounts are provisioned another way). Default false. */
|
|
39
|
+
disableSignUp?: boolean;
|
|
24
40
|
disableCSRFCheck?: boolean;
|
|
25
41
|
/**
|
|
26
42
|
* Cookie-cache lifetime in seconds. This is the session-revocation lag: a
|
|
@@ -29,7 +45,19 @@ interface BetterAuthConfigOptions {
|
|
|
29
45
|
* frequent DB lookups). Defaults to 300 (5 minutes).
|
|
30
46
|
*/
|
|
31
47
|
cookieCacheMaxAge?: number;
|
|
32
|
-
|
|
48
|
+
/**
|
|
49
|
+
* `false` turns off better-auth's own rate limiter (on by default in
|
|
50
|
+
* production), e.g. when the app limits the auth routes itself.
|
|
51
|
+
*/
|
|
52
|
+
rateLimit?: false;
|
|
53
|
+
/**
|
|
54
|
+
* Request headers better-auth reads the client IP from, for its rate
|
|
55
|
+
* limiter and the sessions' `ipAddress` (default `x-forwarded-for`, first
|
|
56
|
+
* entry). Without a usable one, every client shares one rate-limit bucket.
|
|
57
|
+
*/
|
|
58
|
+
ipAddressHeaders?: string[];
|
|
59
|
+
/** better-auth's socialProviders option, as is. */
|
|
60
|
+
socialProviders?: BetterAuthOptions['socialProviders'];
|
|
33
61
|
oidcConfig?: {
|
|
34
62
|
clientId: string;
|
|
35
63
|
clientSecret: string;
|
|
@@ -38,20 +66,74 @@ interface BetterAuthConfigOptions {
|
|
|
38
66
|
authorizationEndpoint?: string;
|
|
39
67
|
tokenEndpoint?: string;
|
|
40
68
|
userinfoEndpoint?: string;
|
|
69
|
+
/**
|
|
70
|
+
* @deprecated Ignored: better-auth takes the JWKS only from the
|
|
71
|
+
* discovery document's `jwks_uri`; point `discoveryEndpoint` at a
|
|
72
|
+
* document that has the right one instead.
|
|
73
|
+
*/
|
|
41
74
|
jwksEndpoint?: string;
|
|
42
75
|
discoveryEndpoint?: string;
|
|
43
76
|
scopes?: string[];
|
|
44
77
|
pkce?: boolean;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
email?: string;
|
|
48
|
-
emailVerified?: string;
|
|
49
|
-
name?: string;
|
|
50
|
-
image?: string;
|
|
51
|
-
extraFields?: Record<string, string>;
|
|
52
|
-
};
|
|
78
|
+
/** Claim names to read the user's fields from, instead of the standard ones. */
|
|
79
|
+
mapping?: OidcClaimMapping;
|
|
53
80
|
};
|
|
54
81
|
}
|
|
82
|
+
/** Claim names `mapOidcProfile` reads the user's fields from. */
|
|
83
|
+
interface OidcClaimMapping {
|
|
84
|
+
/**
|
|
85
|
+
* @deprecated Ignored: better-auth always takes the account's identity
|
|
86
|
+
* from the verified `sub` claim.
|
|
87
|
+
*/
|
|
88
|
+
id?: string;
|
|
89
|
+
email?: string;
|
|
90
|
+
/** The claim is read as verified when it is `true` or `"true"`. */
|
|
91
|
+
emailVerified?: string;
|
|
92
|
+
name?: string;
|
|
93
|
+
image?: string;
|
|
94
|
+
/**
|
|
95
|
+
* @deprecated Ignored: extra user fields need better-auth
|
|
96
|
+
* `user.additionalFields`, which `createBetterAuth` does not declare.
|
|
97
|
+
*/
|
|
98
|
+
extraFields?: Record<string, string>;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The local user fields for an OIDC login (standard claims, with the common
|
|
102
|
+
* non-standard fallbacks). A claim named in `mapping` is read instead of the
|
|
103
|
+
* standard one when the profile has it. No `id`: better-auth takes the
|
|
104
|
+
* account's identity from the verified `sub` (accountSubject) and ignores one
|
|
105
|
+
* returned here.
|
|
106
|
+
*/
|
|
107
|
+
declare function mapOidcProfile(profile: GenericOAuthUserInfo, mapping?: OidcClaimMapping): {
|
|
108
|
+
email: string | null | undefined;
|
|
109
|
+
name: string | undefined;
|
|
110
|
+
image: string | undefined;
|
|
111
|
+
emailVerified: boolean;
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* The generic-oauth provider config for `oidcConfig`. The endpoints left
|
|
115
|
+
* unset come from the issuer's discovery document: better-auth fills only
|
|
116
|
+
* the ones not given, so a default here (e.g. Keycloak's
|
|
117
|
+
* `/protocol/openid-connect/*` paths) would override discovery for every
|
|
118
|
+
* other provider.
|
|
119
|
+
*/
|
|
120
|
+
declare function oidcProviderConfig(oidcConfig: NonNullable<BetterAuthConfigOptions['oidcConfig']>): {
|
|
121
|
+
providerId: string;
|
|
122
|
+
clientId: string;
|
|
123
|
+
clientSecret: string;
|
|
124
|
+
authorizationUrl: string | undefined;
|
|
125
|
+
tokenUrl: string | undefined;
|
|
126
|
+
userInfoUrl: string | undefined;
|
|
127
|
+
discoveryUrl: string;
|
|
128
|
+
scopes: string[];
|
|
129
|
+
pkce: boolean;
|
|
130
|
+
mapProfileToUser: (profile: GenericOAuthUserInfo) => {
|
|
131
|
+
email: string | null | undefined;
|
|
132
|
+
name: string | undefined;
|
|
133
|
+
image: string | undefined;
|
|
134
|
+
emailVerified: boolean;
|
|
135
|
+
};
|
|
136
|
+
};
|
|
55
137
|
declare function createBetterAuth(options: BetterAuthConfigOptions): Auth$1;
|
|
56
138
|
type Auth = ReturnType<typeof createBetterAuth>;
|
|
57
139
|
|
|
@@ -1808,9 +1890,9 @@ declare const mysqlVerification: drizzle_orm_mysql_core.MySqlTableWithColumns<{
|
|
|
1808
1890
|
name: "value";
|
|
1809
1891
|
tableName: "verification";
|
|
1810
1892
|
dataType: "string";
|
|
1811
|
-
columnType: "
|
|
1893
|
+
columnType: "MySqlText";
|
|
1812
1894
|
data: string;
|
|
1813
|
-
driverParam: string
|
|
1895
|
+
driverParam: string;
|
|
1814
1896
|
notNull: true;
|
|
1815
1897
|
hasDefault: false;
|
|
1816
1898
|
isPrimaryKey: false;
|
|
@@ -2415,9 +2497,9 @@ declare const mysqlSchema: {
|
|
|
2415
2497
|
name: "value";
|
|
2416
2498
|
tableName: "verification";
|
|
2417
2499
|
dataType: "string";
|
|
2418
|
-
columnType: "
|
|
2500
|
+
columnType: "MySqlText";
|
|
2419
2501
|
data: string;
|
|
2420
|
-
driverParam: string
|
|
2502
|
+
driverParam: string;
|
|
2421
2503
|
notNull: true;
|
|
2422
2504
|
hasDefault: false;
|
|
2423
2505
|
isPrimaryKey: false;
|
|
@@ -3793,7 +3875,8 @@ interface User {
|
|
|
3793
3875
|
image?: string | null;
|
|
3794
3876
|
createdAt: Date;
|
|
3795
3877
|
updatedAt: Date;
|
|
3796
|
-
|
|
3878
|
+
/** Custom fields: narrow them where they are read. */
|
|
3879
|
+
[key: string]: unknown;
|
|
3797
3880
|
}
|
|
3798
3881
|
interface Account {
|
|
3799
3882
|
id: string;
|
|
@@ -3854,7 +3937,8 @@ interface SignUpInput {
|
|
|
3854
3937
|
email: string;
|
|
3855
3938
|
password: string;
|
|
3856
3939
|
name?: string;
|
|
3857
|
-
|
|
3940
|
+
/** Custom fields: narrow them where they are read. */
|
|
3941
|
+
[key: string]: unknown;
|
|
3858
3942
|
}
|
|
3859
3943
|
/**
|
|
3860
3944
|
* Login input
|
|
@@ -3883,4 +3967,4 @@ interface EmailVerificationRequest {
|
|
|
3883
3967
|
token: string;
|
|
3884
3968
|
}
|
|
3885
3969
|
|
|
3886
|
-
export { type Account, type Auth, type AuthContext, type AuthKitDrizzleDb, type AuthSession, type BetterAuthConfigOptions, type EmailVerificationRequest, type EmailVerificationToken, type PasswordResetConfirm, type PasswordResetRequest, type PasswordResetToken, type SignInInput, type SignUpInput, type User, type Verification, createBetterAuth, mysqlAccount, mysqlSchema, mysqlSession, mysqlUser, mysqlVerification, pgAccount, pgSchema, pgSession, pgUser, pgVerification, sqliteAccount, sqliteSchema, sqliteSession, sqliteUser, sqliteVerification };
|
|
3970
|
+
export { type Account, type Auth, type AuthContext, type AuthKitDrizzleDb, type AuthSession, type BetterAuthConfigOptions, type EmailVerificationRequest, type EmailVerificationToken, type OidcClaimMapping, type PasswordResetConfirm, type PasswordResetRequest, type PasswordResetToken, type SignInInput, type SignUpInput, type User, type Verification, createBetterAuth, mapOidcProfile, mysqlAccount, mysqlSchema, mysqlSession, mysqlUser, mysqlVerification, oidcProviderConfig, pgAccount, pgSchema, pgSession, pgUser, pgVerification, resolveAuthBaseURL, sqliteAccount, sqliteSchema, sqliteSession, sqliteUser, sqliteVerification };
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,13 @@ import { genericOAuth } from "better-auth/plugins/generic-oauth";
|
|
|
5
5
|
|
|
6
6
|
// src/schema.ts
|
|
7
7
|
import { pgTable, text, timestamp, boolean } from "drizzle-orm/pg-core";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
mysqlTable,
|
|
10
|
+
varchar,
|
|
11
|
+
timestamp as mysqlTimestamp,
|
|
12
|
+
boolean as mysqlBoolean,
|
|
13
|
+
text as mysqlText
|
|
14
|
+
} from "drizzle-orm/mysql-core";
|
|
9
15
|
import { sqliteTable, text as sqliteText, integer } from "drizzle-orm/sqlite-core";
|
|
10
16
|
var pgUser = pgTable("user", {
|
|
11
17
|
id: text("id").primaryKey(),
|
|
@@ -92,7 +98,9 @@ var mysqlAccount = mysqlTable("account", {
|
|
|
92
98
|
var mysqlVerification = mysqlTable("verification", {
|
|
93
99
|
id: varchar("id", { length: 36 }).primaryKey(),
|
|
94
100
|
identifier: varchar("identifier", { length: 255 }).notNull(),
|
|
95
|
-
|
|
101
|
+
// text: better-auth stores OAuth state here (JSON longer than 255 characters),
|
|
102
|
+
// which MySQL strict mode rejected, failing every OIDC sign-in.
|
|
103
|
+
value: mysqlText("value").notNull(),
|
|
96
104
|
expiresAt: mysqlTimestamp("expiresAt").notNull(),
|
|
97
105
|
createdAt: mysqlTimestamp("createdAt"),
|
|
98
106
|
updatedAt: mysqlTimestamp("updatedAt")
|
|
@@ -153,26 +161,103 @@ var sqliteSchema = {
|
|
|
153
161
|
};
|
|
154
162
|
|
|
155
163
|
// src/better-auth-config.ts
|
|
164
|
+
import { isProductionEnv } from "@iskra-bun/core";
|
|
156
165
|
var MIN_SECRET_LENGTH = 32;
|
|
166
|
+
var PLACEHOLDER_SECRET_MARKERS = ["change-me", "dev-secret", "dev-only", "your-secret", "placeholder"];
|
|
167
|
+
var normalizeSecret = (value) => value.toLowerCase().replace(/[-_.\s]/g, "");
|
|
168
|
+
function placeholderMarker(secret) {
|
|
169
|
+
const normalized = normalizeSecret(secret);
|
|
170
|
+
return PLACEHOLDER_SECRET_MARKERS.find((marker) => normalized.includes(normalizeSecret(marker)));
|
|
171
|
+
}
|
|
172
|
+
var LOCAL_HOSTNAMES = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]"]);
|
|
173
|
+
function resolveAuthBaseURL(baseURL, who = "createBetterAuth") {
|
|
174
|
+
const resolved = baseURL || process.env.BETTER_AUTH_URL;
|
|
175
|
+
if (resolved) {
|
|
176
|
+
assertHttpsInProduction(resolved, who);
|
|
177
|
+
return resolved;
|
|
178
|
+
}
|
|
179
|
+
if (isProductionEnv()) {
|
|
180
|
+
throw new Error(
|
|
181
|
+
`${who}: set baseURL (or BETTER_AUTH_URL) to the app's public origin in production, e.g. "https://app.example.com"; without it cookies are sent without Secure.`
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
return "http://localhost:3000";
|
|
185
|
+
}
|
|
186
|
+
function assertHttpsInProduction(baseURL, who) {
|
|
187
|
+
if (!isProductionEnv()) return;
|
|
188
|
+
let url;
|
|
189
|
+
try {
|
|
190
|
+
url = new URL(baseURL);
|
|
191
|
+
} catch {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (url.protocol === "https:" || LOCAL_HOSTNAMES.has(url.hostname)) return;
|
|
195
|
+
throw new Error(
|
|
196
|
+
`${who}: baseURL "${baseURL}" must use https in production: better-auth marks the session cookies Secure only for an https baseURL. Plain http is allowed only for localhost, 127.0.0.1 and [::1].`
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
function mapOidcProfile(profile, mapping = {}) {
|
|
200
|
+
const str = (v) => typeof v === "string" && v !== "" ? v : void 0;
|
|
201
|
+
const claim = (name) => name ? profile[name] : void 0;
|
|
202
|
+
const isTrue = (v) => v === true || v === "true";
|
|
203
|
+
const standardVerified = profile.emailVerified === true || isTrue(profile.email_verified);
|
|
204
|
+
const mappedEmail = str(claim(mapping.email));
|
|
205
|
+
const pairedFlag = mappedEmail !== void 0 || !mapping.email ? claim(mapping.emailVerified) : void 0;
|
|
206
|
+
let emailVerified;
|
|
207
|
+
if (pairedFlag !== void 0 && pairedFlag !== null) emailVerified = isTrue(pairedFlag);
|
|
208
|
+
else if (mappedEmail !== void 0) emailVerified = mappedEmail === profile.email && standardVerified;
|
|
209
|
+
else emailVerified = standardVerified;
|
|
210
|
+
return {
|
|
211
|
+
email: mappedEmail ?? profile.email,
|
|
212
|
+
name: str(claim(mapping.name)) ?? (profile.name || str(profile.preferred_username)),
|
|
213
|
+
image: str(claim(mapping.image)) ?? str(profile.picture) ?? profile.image,
|
|
214
|
+
emailVerified
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function oidcProviderConfig(oidcConfig) {
|
|
218
|
+
return {
|
|
219
|
+
providerId: oidcConfig.providerId || "oidc",
|
|
220
|
+
clientId: oidcConfig.clientId,
|
|
221
|
+
clientSecret: oidcConfig.clientSecret,
|
|
222
|
+
authorizationUrl: oidcConfig.authorizationEndpoint || void 0,
|
|
223
|
+
tokenUrl: oidcConfig.tokenEndpoint || void 0,
|
|
224
|
+
userInfoUrl: oidcConfig.userinfoEndpoint || void 0,
|
|
225
|
+
discoveryUrl: oidcConfig.discoveryEndpoint || `${oidcConfig.issuer}/.well-known/openid-configuration`,
|
|
226
|
+
scopes: oidcConfig.scopes || ["openid", "email", "profile"],
|
|
227
|
+
// Secure default: PKCE on. Disabling exposes auth-code
|
|
228
|
+
// interception/injection and requires an explicit false.
|
|
229
|
+
pkce: oidcConfig.pkce !== void 0 ? oidcConfig.pkce : true,
|
|
230
|
+
mapProfileToUser: (profile) => mapOidcProfile(profile, oidcConfig.mapping)
|
|
231
|
+
};
|
|
232
|
+
}
|
|
157
233
|
function createBetterAuth(options) {
|
|
158
234
|
const {
|
|
159
235
|
db,
|
|
160
236
|
adapterType,
|
|
161
237
|
secret,
|
|
162
|
-
baseURL = "http://localhost:3000",
|
|
163
238
|
basePath = "/api/auth",
|
|
164
239
|
trustedOrigins = [],
|
|
165
240
|
enableEmailPassword = true,
|
|
241
|
+
disableSignUp = false,
|
|
166
242
|
disableCSRFCheck = false,
|
|
167
243
|
cookieCacheMaxAge = 5 * 60,
|
|
168
244
|
socialProviders,
|
|
169
|
-
oidcConfig
|
|
245
|
+
oidcConfig,
|
|
246
|
+
rateLimit,
|
|
247
|
+
ipAddressHeaders
|
|
170
248
|
} = options;
|
|
171
249
|
if (!secret || secret.length < MIN_SECRET_LENGTH) {
|
|
172
250
|
throw new Error(
|
|
173
251
|
`auth secret must be at least ${MIN_SECRET_LENGTH} characters; received ${secret ? secret.length : 0}`
|
|
174
252
|
);
|
|
175
253
|
}
|
|
254
|
+
const marker = isProductionEnv() ? placeholderMarker(secret) : void 0;
|
|
255
|
+
if (marker) {
|
|
256
|
+
throw new Error(
|
|
257
|
+
`auth secret looks like a placeholder (it contains "${marker}"); in production set a random secret of at least ${MIN_SECRET_LENGTH} characters, e.g. from \`openssl rand -base64 32\``
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
const baseURL = resolveAuthBaseURL(options.baseURL);
|
|
176
261
|
const baseOrigin = new URL(baseURL).origin;
|
|
177
262
|
const allTrustedOrigins = trustedOrigins.includes(baseOrigin) ? trustedOrigins : [baseOrigin, ...trustedOrigins];
|
|
178
263
|
let schema;
|
|
@@ -199,37 +284,7 @@ function createBetterAuth(options) {
|
|
|
199
284
|
});
|
|
200
285
|
const plugins = [];
|
|
201
286
|
if (oidcConfig) {
|
|
202
|
-
|
|
203
|
-
const tokenUrl = oidcConfig.tokenEndpoint || `${oidcConfig.issuer}/protocol/openid-connect/token`;
|
|
204
|
-
const userInfoUrl = oidcConfig.userinfoEndpoint || `${oidcConfig.issuer}/protocol/openid-connect/userinfo`;
|
|
205
|
-
plugins.push(
|
|
206
|
-
genericOAuth({
|
|
207
|
-
config: [
|
|
208
|
-
{
|
|
209
|
-
providerId: oidcConfig.providerId || "oidc",
|
|
210
|
-
clientId: oidcConfig.clientId,
|
|
211
|
-
clientSecret: oidcConfig.clientSecret,
|
|
212
|
-
authorizationUrl,
|
|
213
|
-
tokenUrl,
|
|
214
|
-
userInfoUrl,
|
|
215
|
-
discoveryUrl: oidcConfig.discoveryEndpoint || `${oidcConfig.issuer}/.well-known/openid-configuration`,
|
|
216
|
-
scopes: oidcConfig.scopes || ["openid", "email", "profile"],
|
|
217
|
-
// Secure default: PKCE on. Disabling exposes auth-code
|
|
218
|
-
// interception/injection and requires an explicit false.
|
|
219
|
-
pkce: oidcConfig.pkce !== void 0 ? oidcConfig.pkce : true,
|
|
220
|
-
mapProfileToUser: (profile) => {
|
|
221
|
-
return {
|
|
222
|
-
id: profile.sub || profile.id,
|
|
223
|
-
email: profile.email,
|
|
224
|
-
name: profile.name || profile.preferred_username,
|
|
225
|
-
image: profile.picture || profile.image,
|
|
226
|
-
emailVerified: profile.email_verified || false
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
]
|
|
231
|
-
})
|
|
232
|
-
);
|
|
287
|
+
plugins.push(genericOAuth({ config: [oidcProviderConfig(oidcConfig)] }));
|
|
233
288
|
}
|
|
234
289
|
return betterAuth({
|
|
235
290
|
database,
|
|
@@ -239,7 +294,8 @@ function createBetterAuth(options) {
|
|
|
239
294
|
trustedOrigins: allTrustedOrigins,
|
|
240
295
|
emailAndPassword: enableEmailPassword ? {
|
|
241
296
|
enabled: true,
|
|
242
|
-
autoSignIn: true
|
|
297
|
+
autoSignIn: true,
|
|
298
|
+
disableSignUp
|
|
243
299
|
} : void 0,
|
|
244
300
|
socialProviders: Object.keys(socialProviders || {}).length > 0 ? socialProviders : void 0,
|
|
245
301
|
plugins,
|
|
@@ -251,24 +307,34 @@ function createBetterAuth(options) {
|
|
|
251
307
|
maxAge: cookieCacheMaxAge
|
|
252
308
|
}
|
|
253
309
|
},
|
|
310
|
+
...rateLimit === false ? { rateLimit: { enabled: false } } : {},
|
|
254
311
|
advanced: {
|
|
255
312
|
disableCSRFCheck,
|
|
256
|
-
|
|
313
|
+
// Pinned: left unset, better-auth skips its Origin check (CSRF on
|
|
314
|
+
// cookie requests) and its callbackURL/redirectTo validation (open
|
|
315
|
+
// redirects) whenever it thinks it runs under test: NODE_ENV=test,
|
|
316
|
+
// or any TEST variable other than "false" (TEST=0 included).
|
|
317
|
+
disableOriginCheck: false,
|
|
318
|
+
generateId: () => crypto.randomUUID().replace(/-/g, ""),
|
|
319
|
+
...ipAddressHeaders ? { ipAddress: { ipAddressHeaders } } : {}
|
|
257
320
|
}
|
|
258
321
|
});
|
|
259
322
|
}
|
|
260
323
|
export {
|
|
261
324
|
createBetterAuth,
|
|
325
|
+
mapOidcProfile,
|
|
262
326
|
mysqlAccount,
|
|
263
327
|
mysqlSchema,
|
|
264
328
|
mysqlSession,
|
|
265
329
|
mysqlUser,
|
|
266
330
|
mysqlVerification,
|
|
331
|
+
oidcProviderConfig,
|
|
267
332
|
pgAccount,
|
|
268
333
|
pgSchema,
|
|
269
334
|
pgSession,
|
|
270
335
|
pgUser,
|
|
271
336
|
pgVerification,
|
|
337
|
+
resolveAuthBaseURL,
|
|
272
338
|
sqliteAccount,
|
|
273
339
|
sqliteSchema,
|
|
274
340
|
sqliteSession,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/better-auth-config.ts","../src/schema.ts"],"sourcesContent":["import { betterAuth, type Auth as BetterAuthInstance } from \"better-auth\";\nimport { drizzleAdapter, type DB as DrizzleAdapterDb } from \"better-auth/adapters/drizzle\";\nimport { genericOAuth } from \"better-auth/plugins/generic-oauth\";\nimport type { PgDatabase, PgQueryResultHKT } from \"drizzle-orm/pg-core\";\nimport type { MySqlDatabase, MySqlQueryResultHKT, PreparedQueryHKTBase } from \"drizzle-orm/mysql-core\";\nimport type { BaseSQLiteDatabase } from \"drizzle-orm/sqlite-core\";\nimport { pgSchema, mysqlSchema, sqliteSchema } from \"./schema\";\n\n/**\n * The Drizzle database handle auth-kit accepts. A union of the supported dialect\n * databases (mirrors web-kit's `WebKitDrizzleDb`) so the public input is a real\n * Drizzle instance rather than `any` leaking into callers. The dialect-core base\n * classes are part of `drizzle-orm` itself, so no driver dependency is required.\n */\nexport type AuthKitDrizzleDb =\n | PgDatabase<PgQueryResultHKT, Record<string, unknown>>\n | MySqlDatabase<MySqlQueryResultHKT, PreparedQueryHKTBase, Record<string, unknown>>\n | BaseSQLiteDatabase<\"sync\" | \"async\", unknown, Record<string, unknown>>;\n\n/** Minimum length, in characters, for the session-signing secret. */\nconst MIN_SECRET_LENGTH = 32;\n\nexport interface BetterAuthConfigOptions {\n db: AuthKitDrizzleDb;\n adapterType: \"postgres\" | \"mysql\" | \"sqlite\";\n secret: string;\n baseURL?: string;\n basePath?: string;\n trustedOrigins?: string[];\n enableEmailPassword?: boolean;\n disableCSRFCheck?: boolean;\n /**\n * Cookie-cache lifetime in seconds. This is the session-revocation lag: a\n * revoked session keeps passing cached cookie checks until the cache entry\n * expires. Lower it to tighten the revocation window (at the cost of more\n * frequent DB lookups). Defaults to 300 (5 minutes).\n */\n cookieCacheMaxAge?: number;\n // deno-lint-ignore no-explicit-any\n socialProviders?: Record<string, any>;\n oidcConfig?: {\n clientId: string;\n clientSecret: string;\n issuer: string;\n providerId?: string;\n authorizationEndpoint?: string;\n tokenEndpoint?: string;\n userinfoEndpoint?: string;\n jwksEndpoint?: string;\n discoveryEndpoint?: string;\n scopes?: string[];\n pkce?: boolean;\n mapping?: {\n id?: string;\n email?: string;\n emailVerified?: string;\n name?: string;\n image?: string;\n extraFields?: Record<string, string>;\n };\n };\n}\n\nexport function createBetterAuth(options: BetterAuthConfigOptions): BetterAuthInstance {\n const {\n db,\n adapterType,\n secret,\n baseURL = \"http://localhost:3000\",\n basePath = \"/api/auth\",\n trustedOrigins = [],\n enableEmailPassword = true,\n disableCSRFCheck = false,\n cookieCacheMaxAge = 5 * 60,\n socialProviders,\n oidcConfig,\n } = options;\n\n // A weak or empty secret signs forgeable sessions, so reject it before\n // betterAuth() ever sees it rather than silently building an insecure auth.\n if (!secret || secret.length < MIN_SECRET_LENGTH) {\n throw new Error(\n `auth secret must be at least ${MIN_SECRET_LENGTH} characters; received ${secret ? secret.length : 0}`,\n );\n }\n\n const baseOrigin = new URL(baseURL).origin;\n const allTrustedOrigins = trustedOrigins.includes(baseOrigin)\n ? trustedOrigins\n : [baseOrigin, ...trustedOrigins];\n\n let schema;\n let provider: \"pg\" | \"mysql\" | \"sqlite\";\n\n switch (adapterType) {\n case \"postgres\":\n schema = pgSchema;\n provider = \"pg\";\n break;\n case \"mysql\":\n schema = mysqlSchema;\n provider = \"mysql\";\n break;\n case \"sqlite\":\n schema = sqliteSchema;\n provider = \"sqlite\";\n break;\n default:\n throw new Error(`Unsupported adapter type: ${adapterType}`);\n }\n\n const database = drizzleAdapter(db as unknown as DrizzleAdapterDb, {\n provider,\n schema\n });\n\n const plugins = [];\n if (oidcConfig) {\n const authorizationUrl = oidcConfig.authorizationEndpoint ||\n `${oidcConfig.issuer}/protocol/openid-connect/auth`;\n const tokenUrl = oidcConfig.tokenEndpoint ||\n `${oidcConfig.issuer}/protocol/openid-connect/token`;\n const userInfoUrl = oidcConfig.userinfoEndpoint ||\n `${oidcConfig.issuer}/protocol/openid-connect/userinfo`;\n\n plugins.push(\n genericOAuth({\n config: [\n {\n providerId: oidcConfig.providerId || \"oidc\",\n clientId: oidcConfig.clientId,\n clientSecret: oidcConfig.clientSecret,\n authorizationUrl,\n tokenUrl,\n userInfoUrl,\n discoveryUrl: oidcConfig.discoveryEndpoint ||\n `${oidcConfig.issuer}/.well-known/openid-configuration`,\n scopes: oidcConfig.scopes || [\"openid\", \"email\", \"profile\"],\n // Secure default: PKCE on. Disabling exposes auth-code\n // interception/injection and requires an explicit false.\n pkce: oidcConfig.pkce !== undefined ? oidcConfig.pkce : true,\n mapProfileToUser: (profile: any) => {\n return {\n id: profile.sub || profile.id,\n email: profile.email,\n name: profile.name || profile.preferred_username,\n image: profile.picture || profile.image,\n emailVerified: profile.email_verified || false,\n };\n },\n },\n ],\n }),\n );\n }\n\n return betterAuth({\n database,\n secret,\n baseURL,\n basePath,\n trustedOrigins: allTrustedOrigins,\n emailAndPassword: enableEmailPassword\n ? {\n enabled: true,\n autoSignIn: true,\n }\n : undefined,\n socialProviders: Object.keys(socialProviders || {}).length > 0 ? socialProviders : undefined,\n plugins,\n session: {\n expiresIn: 60 * 60 * 24 * 7,\n updateAge: 60 * 60 * 24,\n cookieCache: {\n enabled: true,\n maxAge: cookieCacheMaxAge,\n },\n },\n advanced: {\n disableCSRFCheck,\n generateId: () => crypto.randomUUID().replace(/-/g, \"\"),\n },\n }) as unknown as BetterAuthInstance;\n}\n\nexport type Auth = ReturnType<typeof createBetterAuth>;\n","import { pgTable, text, timestamp, boolean } from \"drizzle-orm/pg-core\";\nimport { mysqlTable, varchar, timestamp as mysqlTimestamp, boolean as mysqlBoolean, text as mysqlText } from \"drizzle-orm/mysql-core\";\nimport { sqliteTable, text as sqliteText, integer } from \"drizzle-orm/sqlite-core\";\n\n// ==========================================\n// PostgreSQL Schema\n// ==========================================\n\nexport const pgUser = pgTable(\"user\", {\n id: text(\"id\").primaryKey(),\n name: text(\"name\"),\n email: text(\"email\").notNull().unique(),\n emailVerified: boolean(\"emailVerified\").notNull(),\n image: text(\"image\"),\n createdAt: timestamp(\"createdAt\").notNull(),\n updatedAt: timestamp(\"updatedAt\").notNull()\n});\n\nexport const pgSession = pgTable(\"session\", {\n id: text(\"id\").primaryKey(),\n expiresAt: timestamp(\"expiresAt\").notNull(),\n token: text(\"token\").notNull().unique(),\n createdAt: timestamp(\"createdAt\").notNull(),\n updatedAt: timestamp(\"updatedAt\").notNull(),\n ipAddress: text(\"ipAddress\"),\n userAgent: text(\"userAgent\"),\n userId: text(\"userId\").notNull().references(() => pgUser.id)\n});\n\nexport const pgAccount = pgTable(\"account\", {\n id: text(\"id\").primaryKey(),\n accountId: text(\"accountId\").notNull(),\n providerId: text(\"providerId\").notNull(),\n userId: text(\"userId\").notNull().references(() => pgUser.id),\n accessToken: text(\"accessToken\"),\n refreshToken: text(\"refreshToken\"),\n idToken: text(\"idToken\"),\n accessTokenExpiresAt: timestamp(\"accessTokenExpiresAt\"),\n refreshTokenExpiresAt: timestamp(\"refreshTokenExpiresAt\"),\n scope: text(\"scope\"),\n password: text(\"password\"),\n createdAt: timestamp(\"createdAt\").notNull(),\n updatedAt: timestamp(\"updatedAt\").notNull()\n});\n\nexport const pgVerification = pgTable(\"verification\", {\n id: text(\"id\").primaryKey(),\n identifier: text(\"identifier\").notNull(),\n value: text(\"value\").notNull(),\n expiresAt: timestamp(\"expiresAt\").notNull(),\n createdAt: timestamp(\"createdAt\"),\n updatedAt: timestamp(\"updatedAt\")\n});\n\nexport const pgSchema = {\n user: pgUser,\n session: pgSession,\n account: pgAccount,\n verification: pgVerification\n};\n\n// ==========================================\n// MySQL Schema\n// ==========================================\n\nexport const mysqlUser = mysqlTable(\"user\", {\n id: varchar(\"id\", { length: 36 }).primaryKey(),\n name: varchar(\"name\", { length: 255 }),\n email: varchar(\"email\", { length: 255 }).notNull().unique(),\n emailVerified: mysqlBoolean(\"emailVerified\").notNull(),\n image: varchar(\"image\", { length: 255 }),\n createdAt: mysqlTimestamp(\"createdAt\").notNull(),\n updatedAt: mysqlTimestamp(\"updatedAt\").notNull()\n});\n\nexport const mysqlSession = mysqlTable(\"session\", {\n id: varchar(\"id\", { length: 36 }).primaryKey(),\n expiresAt: mysqlTimestamp(\"expiresAt\").notNull(),\n token: varchar(\"token\", { length: 255 }).notNull().unique(),\n createdAt: mysqlTimestamp(\"createdAt\").notNull(),\n updatedAt: mysqlTimestamp(\"updatedAt\").notNull(),\n ipAddress: varchar(\"ipAddress\", { length: 45 }),\n userAgent: mysqlText(\"userAgent\"),\n userId: varchar(\"userId\", { length: 36 }).notNull().references(() => mysqlUser.id)\n});\n\nexport const mysqlAccount = mysqlTable(\"account\", {\n id: varchar(\"id\", { length: 36 }).primaryKey(),\n accountId: varchar(\"accountId\", { length: 255 }).notNull(),\n providerId: varchar(\"providerId\", { length: 255 }).notNull(),\n userId: varchar(\"userId\", { length: 36 }).notNull().references(() => mysqlUser.id),\n accessToken: mysqlText(\"accessToken\"),\n refreshToken: mysqlText(\"refreshToken\"),\n idToken: mysqlText(\"idToken\"),\n accessTokenExpiresAt: mysqlTimestamp(\"accessTokenExpiresAt\"),\n refreshTokenExpiresAt: mysqlTimestamp(\"refreshTokenExpiresAt\"),\n scope: mysqlText(\"scope\"),\n password: varchar(\"password\", { length: 255 }),\n createdAt: mysqlTimestamp(\"createdAt\").notNull(),\n updatedAt: mysqlTimestamp(\"updatedAt\").notNull()\n});\n\nexport const mysqlVerification = mysqlTable(\"verification\", {\n id: varchar(\"id\", { length: 36 }).primaryKey(),\n identifier: varchar(\"identifier\", { length: 255 }).notNull(),\n value: varchar(\"value\", { length: 255 }).notNull(),\n expiresAt: mysqlTimestamp(\"expiresAt\").notNull(),\n createdAt: mysqlTimestamp(\"createdAt\"),\n updatedAt: mysqlTimestamp(\"updatedAt\")\n});\n\nexport const mysqlSchema = {\n user: mysqlUser,\n session: mysqlSession,\n account: mysqlAccount,\n verification: mysqlVerification\n};\n\n// ==========================================\n// SQLite Schema\n// ==========================================\n\nexport const sqliteUser = sqliteTable(\"user\", {\n id: sqliteText(\"id\").primaryKey(),\n name: sqliteText(\"name\"),\n email: sqliteText(\"email\").notNull().unique(),\n emailVerified: integer(\"emailVerified\", { mode: \"boolean\" }).notNull(),\n image: sqliteText(\"image\"),\n createdAt: integer(\"createdAt\", { mode: \"timestamp\" }).notNull(),\n updatedAt: integer(\"updatedAt\", { mode: \"timestamp\" }).notNull()\n});\n\nexport const sqliteSession = sqliteTable(\"session\", {\n id: sqliteText(\"id\").primaryKey(),\n expiresAt: integer(\"expiresAt\", { mode: \"timestamp\" }).notNull(),\n token: sqliteText(\"token\").notNull().unique(),\n createdAt: integer(\"createdAt\", { mode: \"timestamp\" }).notNull(),\n updatedAt: integer(\"updatedAt\", { mode: \"timestamp\" }).notNull(),\n ipAddress: sqliteText(\"ipAddress\"),\n userAgent: sqliteText(\"userAgent\"),\n userId: sqliteText(\"userId\").notNull().references(() => sqliteUser.id)\n});\n\nexport const sqliteAccount = sqliteTable(\"account\", {\n id: sqliteText(\"id\").primaryKey(),\n accountId: sqliteText(\"accountId\").notNull(),\n providerId: sqliteText(\"providerId\").notNull(),\n userId: sqliteText(\"userId\").notNull().references(() => sqliteUser.id),\n accessToken: sqliteText(\"accessToken\"),\n refreshToken: sqliteText(\"refreshToken\"),\n idToken: sqliteText(\"idToken\"),\n accessTokenExpiresAt: integer(\"accessTokenExpiresAt\", { mode: \"timestamp\" }),\n refreshTokenExpiresAt: integer(\"refreshTokenExpiresAt\", { mode: \"timestamp\" }),\n scope: sqliteText(\"scope\"),\n password: sqliteText(\"password\"),\n createdAt: integer(\"createdAt\", { mode: \"timestamp\" }).notNull(),\n updatedAt: integer(\"updatedAt\", { mode: \"timestamp\" }).notNull()\n});\n\nexport const sqliteVerification = sqliteTable(\"verification\", {\n id: sqliteText(\"id\").primaryKey(),\n identifier: sqliteText(\"identifier\").notNull(),\n value: sqliteText(\"value\").notNull(),\n expiresAt: integer(\"expiresAt\", { mode: \"timestamp\" }).notNull(),\n createdAt: integer(\"createdAt\", { mode: \"timestamp\" }),\n updatedAt: integer(\"updatedAt\", { mode: \"timestamp\" })\n});\n\nexport const sqliteSchema = {\n user: sqliteUser,\n session: sqliteSession,\n account: sqliteAccount,\n verification: sqliteVerification\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/better-auth-config.ts","../src/schema.ts"],"sourcesContent":["import { betterAuth, type Auth as BetterAuthInstance, type BetterAuthOptions } from 'better-auth';\nimport { drizzleAdapter, type DB as DrizzleAdapterDb } from 'better-auth/adapters/drizzle';\nimport { genericOAuth, type GenericOAuthUserInfo } from 'better-auth/plugins/generic-oauth';\nimport type { PgDatabase, PgQueryResultHKT } from 'drizzle-orm/pg-core';\nimport type { MySqlDatabase, MySqlQueryResultHKT, PreparedQueryHKTBase } from 'drizzle-orm/mysql-core';\nimport type { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core';\nimport { pgSchema, mysqlSchema, sqliteSchema } from './schema';\nimport { isProductionEnv } from '@iskra-bun/core';\n\n/**\n * The Drizzle database handle auth-kit accepts. A union of the supported dialect\n * databases (mirrors web-kit's `WebKitDrizzleDb`) so the public input is a real\n * Drizzle instance rather than `any` leaking into callers. The dialect-core base\n * classes are part of `drizzle-orm` itself, so no driver dependency is required.\n */\nexport type AuthKitDrizzleDb =\n | PgDatabase<PgQueryResultHKT, Record<string, unknown>>\n | MySqlDatabase<MySqlQueryResultHKT, PreparedQueryHKTBase, Record<string, unknown>>\n | BaseSQLiteDatabase<'sync' | 'async', unknown, Record<string, unknown>>;\n\n/** Minimum length, in characters, for the session-signing secret. */\nconst MIN_SECRET_LENGTH = 32;\n\n/**\n * Pieces of the sample secrets docs and `.env.example` files ship. Compared\n * without case, `-`, `_`, `.` or spaces, so `change-me` also matches\n * `changeme` and `CHANGE_ME`.\n */\nconst PLACEHOLDER_SECRET_MARKERS = ['change-me', 'dev-secret', 'dev-only', 'your-secret', 'placeholder'];\n\nconst normalizeSecret = (value: string) => value.toLowerCase().replace(/[-_.\\s]/g, '');\n\n/** The placeholder marker `secret` contains, if any. */\nfunction placeholderMarker(secret: string): string | undefined {\n const normalized = normalizeSecret(secret);\n return PLACEHOLDER_SECRET_MARKERS.find((marker) => normalized.includes(normalizeSecret(marker)));\n}\n\n/** Hosts a production baseURL may reach over plain http (e.g. docker compose on one machine). */\nconst LOCAL_HOSTNAMES = new Set(['localhost', '127.0.0.1', '[::1]']);\n\n/**\n * The origin better-auth runs on: `baseURL`, else `BETTER_AUTH_URL`, else\n * `http://localhost:3000` outside production. It decides the cookies'\n * `Secure` flag and is a trusted origin, so production requires one and it\n * must be https (plain http only for localhost, 127.0.0.1 and [::1]). `who`\n * prefixes the error messages.\n */\nexport function resolveAuthBaseURL(baseURL?: string, who = 'createBetterAuth'): string {\n const resolved = baseURL || process.env.BETTER_AUTH_URL;\n if (resolved) {\n assertHttpsInProduction(resolved, who);\n return resolved;\n }\n if (isProductionEnv()) {\n throw new Error(\n `${who}: set baseURL (or BETTER_AUTH_URL) to the app's public origin in production, ` +\n 'e.g. \"https://app.example.com\"; without it cookies are sent without Secure.',\n );\n }\n return 'http://localhost:3000';\n}\n\n/**\n * better-auth marks the session cookies Secure only for an https baseURL, so\n * an http:// one in production sent them over plain HTTP as well.\n */\nfunction assertHttpsInProduction(baseURL: string, who: string): void {\n if (!isProductionEnv()) return;\n let url: URL;\n try {\n url = new URL(baseURL);\n } catch {\n return; // an invalid URL is reported by the caller\n }\n if (url.protocol === 'https:' || LOCAL_HOSTNAMES.has(url.hostname)) return;\n throw new Error(\n `${who}: baseURL \"${baseURL}\" must use https in production: better-auth marks the session cookies ` +\n 'Secure only for an https baseURL. Plain http is allowed only for localhost, 127.0.0.1 and [::1].',\n );\n}\n\nexport interface BetterAuthConfigOptions {\n db: AuthKitDrizzleDb;\n adapterType: 'postgres' | 'mysql' | 'sqlite';\n secret: string;\n /**\n * The app's public origin. Defaults to `BETTER_AUTH_URL`, then (outside\n * production only) `http://localhost:3000`; must be https in production\n * unless it is localhost. See `resolveAuthBaseURL`.\n */\n baseURL?: string;\n basePath?: string;\n trustedOrigins?: string[];\n enableEmailPassword?: boolean;\n /** Reject `/sign-up/email` (accounts are provisioned another way). Default false. */\n disableSignUp?: boolean;\n disableCSRFCheck?: boolean;\n /**\n * Cookie-cache lifetime in seconds. This is the session-revocation lag: a\n * revoked session keeps passing cached cookie checks until the cache entry\n * expires. Lower it to tighten the revocation window (at the cost of more\n * frequent DB lookups). Defaults to 300 (5 minutes).\n */\n cookieCacheMaxAge?: number;\n /**\n * `false` turns off better-auth's own rate limiter (on by default in\n * production), e.g. when the app limits the auth routes itself.\n */\n rateLimit?: false;\n /**\n * Request headers better-auth reads the client IP from, for its rate\n * limiter and the sessions' `ipAddress` (default `x-forwarded-for`, first\n * entry). Without a usable one, every client shares one rate-limit bucket.\n */\n ipAddressHeaders?: string[];\n /** better-auth's socialProviders option, as is. */\n socialProviders?: BetterAuthOptions['socialProviders'];\n oidcConfig?: {\n clientId: string;\n clientSecret: string;\n issuer: string;\n providerId?: string;\n authorizationEndpoint?: string;\n tokenEndpoint?: string;\n userinfoEndpoint?: string;\n /**\n * @deprecated Ignored: better-auth takes the JWKS only from the\n * discovery document's `jwks_uri`; point `discoveryEndpoint` at a\n * document that has the right one instead.\n */\n jwksEndpoint?: string;\n discoveryEndpoint?: string;\n scopes?: string[];\n pkce?: boolean;\n /** Claim names to read the user's fields from, instead of the standard ones. */\n mapping?: OidcClaimMapping;\n };\n}\n\n/** Claim names `mapOidcProfile` reads the user's fields from. */\nexport interface OidcClaimMapping {\n /**\n * @deprecated Ignored: better-auth always takes the account's identity\n * from the verified `sub` claim.\n */\n id?: string;\n email?: string;\n /** The claim is read as verified when it is `true` or `\"true\"`. */\n emailVerified?: string;\n name?: string;\n image?: string;\n /**\n * @deprecated Ignored: extra user fields need better-auth\n * `user.additionalFields`, which `createBetterAuth` does not declare.\n */\n extraFields?: Record<string, string>;\n}\n\n/**\n * The local user fields for an OIDC login (standard claims, with the common\n * non-standard fallbacks). A claim named in `mapping` is read instead of the\n * standard one when the profile has it. No `id`: better-auth takes the\n * account's identity from the verified `sub` (accountSubject) and ignores one\n * returned here.\n */\nexport function mapOidcProfile(profile: GenericOAuthUserInfo, mapping: OidcClaimMapping = {}) {\n const str = (v: unknown) => (typeof v === 'string' && v !== '' ? v : undefined);\n const claim = (name: string | undefined) => (name ? profile[name] : undefined);\n const isTrue = (v: unknown) => v === true || v === 'true';\n const standardVerified = profile.emailVerified === true || isTrue(profile.email_verified);\n const mappedEmail = str(claim(mapping.email));\n // better-auth links a login to the local user with the same email when it\n // is verified, so a flag must vouch for the address actually returned.\n // A mapped flag pairs with the mapped email (or with the standard one when\n // mapping.email is not set); the standard flag only vouches for the\n // standard email.\n const pairedFlag = mappedEmail !== undefined || !mapping.email ? claim(mapping.emailVerified) : undefined;\n let emailVerified: boolean;\n if (pairedFlag !== undefined && pairedFlag !== null) emailVerified = isTrue(pairedFlag);\n else if (mappedEmail !== undefined) emailVerified = mappedEmail === profile.email && standardVerified;\n else emailVerified = standardVerified;\n return {\n email: mappedEmail ?? profile.email,\n name: str(claim(mapping.name)) ?? (profile.name || str(profile.preferred_username)),\n image: str(claim(mapping.image)) ?? str(profile.picture) ?? profile.image,\n emailVerified,\n };\n}\n\n/**\n * The generic-oauth provider config for `oidcConfig`. The endpoints left\n * unset come from the issuer's discovery document: better-auth fills only\n * the ones not given, so a default here (e.g. Keycloak's\n * `/protocol/openid-connect/*` paths) would override discovery for every\n * other provider.\n */\nexport function oidcProviderConfig(oidcConfig: NonNullable<BetterAuthConfigOptions['oidcConfig']>) {\n return {\n providerId: oidcConfig.providerId || 'oidc',\n clientId: oidcConfig.clientId,\n clientSecret: oidcConfig.clientSecret,\n authorizationUrl: oidcConfig.authorizationEndpoint || undefined,\n tokenUrl: oidcConfig.tokenEndpoint || undefined,\n userInfoUrl: oidcConfig.userinfoEndpoint || undefined,\n discoveryUrl: oidcConfig.discoveryEndpoint || `${oidcConfig.issuer}/.well-known/openid-configuration`,\n scopes: oidcConfig.scopes || ['openid', 'email', 'profile'],\n // Secure default: PKCE on. Disabling exposes auth-code\n // interception/injection and requires an explicit false.\n pkce: oidcConfig.pkce !== undefined ? oidcConfig.pkce : true,\n mapProfileToUser: (profile: GenericOAuthUserInfo) => mapOidcProfile(profile, oidcConfig.mapping),\n };\n}\n\nexport function createBetterAuth(options: BetterAuthConfigOptions): BetterAuthInstance {\n const {\n db,\n adapterType,\n secret,\n basePath = '/api/auth',\n trustedOrigins = [],\n enableEmailPassword = true,\n disableSignUp = false,\n disableCSRFCheck = false,\n cookieCacheMaxAge = 5 * 60,\n socialProviders,\n oidcConfig,\n rateLimit,\n ipAddressHeaders,\n } = options;\n\n // A weak or empty secret signs forgeable sessions, so reject it before\n // betterAuth() ever sees it rather than silently building an insecure auth.\n if (!secret || secret.length < MIN_SECRET_LENGTH) {\n throw new Error(\n `auth secret must be at least ${MIN_SECRET_LENGTH} characters; received ${secret ? secret.length : 0}`,\n );\n }\n // A sample secret left in production is public: with it anyone can sign\n // the session cookie cache, which is trusted without a database lookup,\n // and so forge a session for any user.\n const marker = isProductionEnv() ? placeholderMarker(secret) : undefined;\n if (marker) {\n throw new Error(\n `auth secret looks like a placeholder (it contains \"${marker}\"); in production set a random secret ` +\n `of at least ${MIN_SECRET_LENGTH} characters, e.g. from \\`openssl rand -base64 32\\``,\n );\n }\n\n const baseURL = resolveAuthBaseURL(options.baseURL);\n const baseOrigin = new URL(baseURL).origin;\n const allTrustedOrigins = trustedOrigins.includes(baseOrigin) ? trustedOrigins : [baseOrigin, ...trustedOrigins];\n\n let schema;\n let provider: 'pg' | 'mysql' | 'sqlite';\n\n switch (adapterType) {\n case 'postgres':\n schema = pgSchema;\n provider = 'pg';\n break;\n case 'mysql':\n schema = mysqlSchema;\n provider = 'mysql';\n break;\n case 'sqlite':\n schema = sqliteSchema;\n provider = 'sqlite';\n break;\n default:\n throw new Error(`Unsupported adapter type: ${adapterType}`);\n }\n\n const database = drizzleAdapter(db as unknown as DrizzleAdapterDb, {\n provider,\n schema,\n });\n\n const plugins = [];\n if (oidcConfig) {\n plugins.push(genericOAuth({ config: [oidcProviderConfig(oidcConfig)] }));\n }\n\n return betterAuth({\n database,\n secret,\n baseURL,\n basePath,\n trustedOrigins: allTrustedOrigins,\n emailAndPassword: enableEmailPassword\n ? {\n enabled: true,\n autoSignIn: true,\n disableSignUp,\n }\n : undefined,\n socialProviders: Object.keys(socialProviders || {}).length > 0 ? socialProviders : undefined,\n plugins,\n session: {\n expiresIn: 60 * 60 * 24 * 7,\n updateAge: 60 * 60 * 24,\n cookieCache: {\n enabled: true,\n maxAge: cookieCacheMaxAge,\n },\n },\n ...(rateLimit === false ? { rateLimit: { enabled: false } } : {}),\n advanced: {\n disableCSRFCheck,\n // Pinned: left unset, better-auth skips its Origin check (CSRF on\n // cookie requests) and its callbackURL/redirectTo validation (open\n // redirects) whenever it thinks it runs under test: NODE_ENV=test,\n // or any TEST variable other than \"false\" (TEST=0 included).\n disableOriginCheck: false,\n generateId: () => crypto.randomUUID().replace(/-/g, ''),\n ...(ipAddressHeaders ? { ipAddress: { ipAddressHeaders } } : {}),\n },\n }) as unknown as BetterAuthInstance;\n}\n\nexport type Auth = ReturnType<typeof createBetterAuth>;\n","import { pgTable, text, timestamp, boolean } from 'drizzle-orm/pg-core';\nimport {\n mysqlTable,\n varchar,\n timestamp as mysqlTimestamp,\n boolean as mysqlBoolean,\n text as mysqlText,\n} from 'drizzle-orm/mysql-core';\nimport { sqliteTable, text as sqliteText, integer } from 'drizzle-orm/sqlite-core';\n\n// ==========================================\n// PostgreSQL Schema\n// ==========================================\n\nexport const pgUser = pgTable('user', {\n id: text('id').primaryKey(),\n name: text('name'),\n email: text('email').notNull().unique(),\n emailVerified: boolean('emailVerified').notNull(),\n image: text('image'),\n createdAt: timestamp('createdAt').notNull(),\n updatedAt: timestamp('updatedAt').notNull(),\n});\n\nexport const pgSession = pgTable('session', {\n id: text('id').primaryKey(),\n expiresAt: timestamp('expiresAt').notNull(),\n token: text('token').notNull().unique(),\n createdAt: timestamp('createdAt').notNull(),\n updatedAt: timestamp('updatedAt').notNull(),\n ipAddress: text('ipAddress'),\n userAgent: text('userAgent'),\n userId: text('userId')\n .notNull()\n .references(() => pgUser.id),\n});\n\nexport const pgAccount = pgTable('account', {\n id: text('id').primaryKey(),\n accountId: text('accountId').notNull(),\n providerId: text('providerId').notNull(),\n userId: text('userId')\n .notNull()\n .references(() => pgUser.id),\n accessToken: text('accessToken'),\n refreshToken: text('refreshToken'),\n idToken: text('idToken'),\n accessTokenExpiresAt: timestamp('accessTokenExpiresAt'),\n refreshTokenExpiresAt: timestamp('refreshTokenExpiresAt'),\n scope: text('scope'),\n password: text('password'),\n createdAt: timestamp('createdAt').notNull(),\n updatedAt: timestamp('updatedAt').notNull(),\n});\n\nexport const pgVerification = pgTable('verification', {\n id: text('id').primaryKey(),\n identifier: text('identifier').notNull(),\n value: text('value').notNull(),\n expiresAt: timestamp('expiresAt').notNull(),\n createdAt: timestamp('createdAt'),\n updatedAt: timestamp('updatedAt'),\n});\n\nexport const pgSchema = {\n user: pgUser,\n session: pgSession,\n account: pgAccount,\n verification: pgVerification,\n};\n\n// ==========================================\n// MySQL Schema\n// ==========================================\n\nexport const mysqlUser = mysqlTable('user', {\n id: varchar('id', { length: 36 }).primaryKey(),\n name: varchar('name', { length: 255 }),\n email: varchar('email', { length: 255 }).notNull().unique(),\n emailVerified: mysqlBoolean('emailVerified').notNull(),\n image: varchar('image', { length: 255 }),\n createdAt: mysqlTimestamp('createdAt').notNull(),\n updatedAt: mysqlTimestamp('updatedAt').notNull(),\n});\n\nexport const mysqlSession = mysqlTable('session', {\n id: varchar('id', { length: 36 }).primaryKey(),\n expiresAt: mysqlTimestamp('expiresAt').notNull(),\n token: varchar('token', { length: 255 }).notNull().unique(),\n createdAt: mysqlTimestamp('createdAt').notNull(),\n updatedAt: mysqlTimestamp('updatedAt').notNull(),\n ipAddress: varchar('ipAddress', { length: 45 }),\n userAgent: mysqlText('userAgent'),\n userId: varchar('userId', { length: 36 })\n .notNull()\n .references(() => mysqlUser.id),\n});\n\nexport const mysqlAccount = mysqlTable('account', {\n id: varchar('id', { length: 36 }).primaryKey(),\n accountId: varchar('accountId', { length: 255 }).notNull(),\n providerId: varchar('providerId', { length: 255 }).notNull(),\n userId: varchar('userId', { length: 36 })\n .notNull()\n .references(() => mysqlUser.id),\n accessToken: mysqlText('accessToken'),\n refreshToken: mysqlText('refreshToken'),\n idToken: mysqlText('idToken'),\n accessTokenExpiresAt: mysqlTimestamp('accessTokenExpiresAt'),\n refreshTokenExpiresAt: mysqlTimestamp('refreshTokenExpiresAt'),\n scope: mysqlText('scope'),\n password: varchar('password', { length: 255 }),\n createdAt: mysqlTimestamp('createdAt').notNull(),\n updatedAt: mysqlTimestamp('updatedAt').notNull(),\n});\n\nexport const mysqlVerification = mysqlTable('verification', {\n id: varchar('id', { length: 36 }).primaryKey(),\n identifier: varchar('identifier', { length: 255 }).notNull(),\n // text: better-auth stores OAuth state here (JSON longer than 255 characters),\n // which MySQL strict mode rejected, failing every OIDC sign-in.\n value: mysqlText('value').notNull(),\n expiresAt: mysqlTimestamp('expiresAt').notNull(),\n createdAt: mysqlTimestamp('createdAt'),\n updatedAt: mysqlTimestamp('updatedAt'),\n});\n\nexport const mysqlSchema = {\n user: mysqlUser,\n session: mysqlSession,\n account: mysqlAccount,\n verification: mysqlVerification,\n};\n\n// ==========================================\n// SQLite Schema\n// ==========================================\n\nexport const sqliteUser = sqliteTable('user', {\n id: sqliteText('id').primaryKey(),\n name: sqliteText('name'),\n email: sqliteText('email').notNull().unique(),\n emailVerified: integer('emailVerified', { mode: 'boolean' }).notNull(),\n image: sqliteText('image'),\n createdAt: integer('createdAt', { mode: 'timestamp' }).notNull(),\n updatedAt: integer('updatedAt', { mode: 'timestamp' }).notNull(),\n});\n\nexport const sqliteSession = sqliteTable('session', {\n id: sqliteText('id').primaryKey(),\n expiresAt: integer('expiresAt', { mode: 'timestamp' }).notNull(),\n token: sqliteText('token').notNull().unique(),\n createdAt: integer('createdAt', { mode: 'timestamp' }).notNull(),\n updatedAt: integer('updatedAt', { mode: 'timestamp' }).notNull(),\n ipAddress: sqliteText('ipAddress'),\n userAgent: sqliteText('userAgent'),\n userId: sqliteText('userId')\n .notNull()\n .references(() => sqliteUser.id),\n});\n\nexport const sqliteAccount = sqliteTable('account', {\n id: sqliteText('id').primaryKey(),\n accountId: sqliteText('accountId').notNull(),\n providerId: sqliteText('providerId').notNull(),\n userId: sqliteText('userId')\n .notNull()\n .references(() => sqliteUser.id),\n accessToken: sqliteText('accessToken'),\n refreshToken: sqliteText('refreshToken'),\n idToken: sqliteText('idToken'),\n accessTokenExpiresAt: integer('accessTokenExpiresAt', { mode: 'timestamp' }),\n refreshTokenExpiresAt: integer('refreshTokenExpiresAt', { mode: 'timestamp' }),\n scope: sqliteText('scope'),\n password: sqliteText('password'),\n createdAt: integer('createdAt', { mode: 'timestamp' }).notNull(),\n updatedAt: integer('updatedAt', { mode: 'timestamp' }).notNull(),\n});\n\nexport const sqliteVerification = sqliteTable('verification', {\n id: sqliteText('id').primaryKey(),\n identifier: sqliteText('identifier').notNull(),\n value: sqliteText('value').notNull(),\n expiresAt: integer('expiresAt', { mode: 'timestamp' }).notNull(),\n createdAt: integer('createdAt', { mode: 'timestamp' }),\n updatedAt: integer('updatedAt', { mode: 'timestamp' }),\n});\n\nexport const sqliteSchema = {\n user: sqliteUser,\n session: sqliteSession,\n account: sqliteAccount,\n verification: sqliteVerification,\n};\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iskra-bun/auth-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Integracion de autenticacion de Iskra basada en better-auth, agnostica del transporte.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"iskra",
|
|
@@ -19,6 +19,9 @@
|
|
|
19
19
|
},
|
|
20
20
|
"homepage": "https://github.com/fearful/iskra/tree/main/packages/auth-kit#readme",
|
|
21
21
|
"bugs": "https://github.com/fearful/iskra/issues",
|
|
22
|
+
"engines": {
|
|
23
|
+
"bun": ">=1.3.0"
|
|
24
|
+
},
|
|
22
25
|
"type": "module",
|
|
23
26
|
"main": "./dist/index.js",
|
|
24
27
|
"module": "./dist/index.js",
|
|
@@ -46,9 +49,9 @@
|
|
|
46
49
|
"build": "tsup --config ../../tsup.config.ts"
|
|
47
50
|
},
|
|
48
51
|
"dependencies": {
|
|
49
|
-
"@iskra-bun/core": "0.
|
|
50
|
-
"better-auth": "^1.
|
|
51
|
-
"drizzle-orm": "^0.45.
|
|
52
|
+
"@iskra-bun/core": "^0.2.0",
|
|
53
|
+
"better-auth": "^1.6.33",
|
|
54
|
+
"drizzle-orm": "^0.45.2"
|
|
52
55
|
},
|
|
53
56
|
"devDependencies": {
|
|
54
57
|
"@types/bun": "^1.3.5",
|