@contentgrowth/content-auth 0.3.3 → 0.4.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.
@@ -1135,6 +1135,61 @@ interface EmailNormalizationConfig {
1135
1135
  /** Column name in users table. Default: 'normalized_email' */
1136
1136
  columnName?: string;
1137
1137
  }
1138
+ /**
1139
+ * Field attribute for additional fields in custom schema
1140
+ */
1141
+ interface FieldAttribute {
1142
+ type: string | string[];
1143
+ required?: boolean;
1144
+ defaultValue?: any;
1145
+ input?: boolean;
1146
+ }
1147
+ /**
1148
+ * Table mapping configuration for a single model
1149
+ */
1150
+ interface TableMapping {
1151
+ /** Custom table name in the database */
1152
+ tableName?: string;
1153
+ /** Map Better Auth field names to your database column names */
1154
+ fields?: Record<string, string>;
1155
+ /** Additional fields in your custom table */
1156
+ additionalFields?: Record<string, FieldAttribute>;
1157
+ }
1158
+ /**
1159
+ * Custom schema mapping to use existing tables with Better Auth.
1160
+ * This allows you to map Better Auth's default table/column names to your existing database schema.
1161
+ *
1162
+ * @example
1163
+ * ```typescript
1164
+ * schemaMapping: {
1165
+ * user: {
1166
+ * tableName: "tenant_admins",
1167
+ * fields: { id: "firebase_uid", createdAt: "created_at" },
1168
+ * additionalFields: { role: { type: "string" }, tenant_id: { type: "string" } }
1169
+ * },
1170
+ * organization: {
1171
+ * tableName: "tenants",
1172
+ * fields: { id: "tenant_id", metadata: "settings" }
1173
+ * }
1174
+ * }
1175
+ * ```
1176
+ */
1177
+ interface SchemaMapping {
1178
+ /** Map Better Auth's 'user' model */
1179
+ user?: TableMapping;
1180
+ /** Map Better Auth's 'session' model */
1181
+ session?: TableMapping;
1182
+ /** Map Better Auth's 'account' model */
1183
+ account?: TableMapping;
1184
+ /** Map Better Auth's 'verification' model */
1185
+ verification?: TableMapping;
1186
+ /** Map Better Auth's 'organization' model (from organization plugin) */
1187
+ organization?: TableMapping;
1188
+ /** Map Better Auth's 'member' model (from organization plugin) */
1189
+ member?: TableMapping;
1190
+ /** Map Better Auth's 'invitation' model (from organization plugin) */
1191
+ invitation?: TableMapping;
1192
+ }
1138
1193
  interface AuthConfig {
1139
1194
  /**
1140
1195
  * The database instance or D1 binding.
@@ -1182,6 +1237,12 @@ interface AuthConfig {
1182
1237
  * Requires a 'normalized_email' column in the users table.
1183
1238
  */
1184
1239
  emailNormalization?: EmailNormalizationConfig;
1240
+ /**
1241
+ * Custom schema mapping to use existing tables with Better Auth.
1242
+ * Maps Better Auth's default table/column names to your existing database schema.
1243
+ * If not provided, uses default table names (users, sessions, accounts, etc.).
1244
+ */
1245
+ schemaMapping?: SchemaMapping;
1185
1246
  [key: string]: any;
1186
1247
  }
1187
1248
  declare const createAuth: (config: AuthConfig) => better_auth.Auth<any>;
@@ -1191,4 +1252,4 @@ declare const createAuthApp: (config: AuthConfig) => {
1191
1252
  auth: better_auth.Auth<any>;
1192
1253
  };
1193
1254
 
1194
- export { type AuthConfig, type EmailNormalizationConfig, type TurnstileConfig, authMiddleware, createAuth, createAuthApp, getInvitationLink, getSessionToken, isGmailAddress, normalizeEmail, schema, verifyTurnstile };
1255
+ export { type AuthConfig, type EmailNormalizationConfig, type FieldAttribute, type SchemaMapping, type TableMapping, type TurnstileConfig, authMiddleware, createAuth, createAuthApp, getInvitationLink, getSessionToken, isGmailAddress, normalizeEmail, schema, verifyTurnstile };
@@ -9,7 +9,7 @@ import {
9
9
  normalizeEmail,
10
10
  schema_exports,
11
11
  verifyTurnstile
12
- } from "../chunk-HTFOOF6M.js";
12
+ } from "../chunk-I7BMKFVZ.js";
13
13
  import "../chunk-R5U7XKVJ.js";
14
14
  export {
15
15
  Hono,
@@ -33,11 +33,21 @@ async function verifyTurnstile(secretKey, token, remoteIp) {
33
33
  },
34
34
  body: formData.toString()
35
35
  });
36
+ let result;
37
+ try {
38
+ result = await response.json();
39
+ } catch (e) {
40
+ console.error(`[Turnstile] Failed to parse response: ${response.status}`);
41
+ return { success: false, error: "Security verification failed. Please try again." };
42
+ }
36
43
  if (!response.ok) {
37
- console.error(`[Turnstile] Siteverify API error: ${response.status}`);
38
- return { success: false, error: `API error: ${response.status}` };
44
+ const errorCodes = result["error-codes"] || [];
45
+ console.error(`[Turnstile] Siteverify API error ${response.status}: ${errorCodes.join(", ")}`);
46
+ if (errorCodes.length > 0) {
47
+ return { success: false, error: mapTurnstileError(errorCodes) };
48
+ }
49
+ return { success: false, error: "Security verification failed. Please try again." };
39
50
  }
40
- const result = await response.json();
41
51
  if (result.success) {
42
52
  return { success: true, hostname: result.hostname };
43
53
  } else {
@@ -293,6 +303,7 @@ var createAuth = (config) => {
293
303
  emailVerification,
294
304
  turnstile: turnstileConfig,
295
305
  emailNormalization,
306
+ schemaMapping,
296
307
  ...rest
297
308
  } = config;
298
309
  let adapterOptions = {
@@ -307,6 +318,24 @@ var createAuth = (config) => {
307
318
  invitation: invitations
308
319
  }
309
320
  };
321
+ const buildModelConfig = (mapping) => {
322
+ if (!mapping) return void 0;
323
+ const config2 = {};
324
+ if (mapping.tableName) {
325
+ config2.modelName = mapping.tableName;
326
+ }
327
+ if (mapping.fields) {
328
+ config2.fields = mapping.fields;
329
+ }
330
+ if (mapping.additionalFields) {
331
+ config2.additionalFields = mapping.additionalFields;
332
+ }
333
+ return Object.keys(config2).length > 0 ? config2 : void 0;
334
+ };
335
+ const userConfig = buildModelConfig(schemaMapping?.user);
336
+ const sessionConfig = buildModelConfig(schemaMapping?.session);
337
+ const userTableName = schemaMapping?.user?.tableName || "users";
338
+ const userIdColumn = schemaMapping?.user?.fields?.id || "id";
310
339
  const emailConfig = rest.emailAndPassword || { enabled: true };
311
340
  const { emailAndPassword, hooks: userHooks, ...otherOptions } = rest;
312
341
  const emailPasswordOptions = {
@@ -343,7 +372,7 @@ var createAuth = (config) => {
343
372
  if (emailNormalization?.enabled && body.email && rawDb?.prepare) {
344
373
  const normalized = normalizeEmail(body.email);
345
374
  const existing = await rawDb.prepare(
346
- `SELECT id FROM users WHERE ${normalizedEmailColumn} = ?`
375
+ `SELECT ${userIdColumn} FROM ${userTableName} WHERE ${normalizedEmailColumn} = ?`
347
376
  ).bind(normalized).first();
348
377
  if (existing) {
349
378
  console.warn(`[ContentAuth] Duplicate normalized email detected: ${normalized}`);
@@ -369,7 +398,7 @@ var createAuth = (config) => {
369
398
  try {
370
399
  const normalized = normalizeEmail(user.email);
371
400
  await rawDb.prepare(
372
- `UPDATE users SET ${normalizedEmailColumn} = ? WHERE id = ? AND (${normalizedEmailColumn} IS NULL OR ${normalizedEmailColumn} != ?)`
401
+ `UPDATE ${userTableName} SET ${normalizedEmailColumn} = ? WHERE ${userIdColumn} = ? AND (${normalizedEmailColumn} IS NULL OR ${normalizedEmailColumn} != ?)`
373
402
  ).bind(normalized, user.id, normalized).run();
374
403
  } catch (e) {
375
404
  console.error(`[ContentAuth] Failed to set normalized_email: ${e.message}`);
@@ -389,6 +418,9 @@ var createAuth = (config) => {
389
418
  emailAndPassword: emailPasswordOptions,
390
419
  // Pass emailVerification config if provided
391
420
  ...emailVerification ? { emailVerification } : {},
421
+ // Model configs for custom table/column mapping
422
+ ...userConfig ? { user: userConfig } : {},
423
+ ...sessionConfig ? { session: sessionConfig } : {},
392
424
  // Merge content-auth hooks with user hooks
393
425
  hooks: contentAuthHooks,
394
426
  ...otherOptions
@@ -628,7 +628,7 @@ declare const createClient: (baseUrl?: string) => {
628
628
  sortDirection?: "asc" | "desc" | undefined;
629
629
  filterField?: string | undefined;
630
630
  filterValue?: string | number | boolean | undefined;
631
- filterOperator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "contains" | undefined;
631
+ filterOperator?: "eq" | "ne" | "gt" | "gte" | "lt" | "lte" | "contains" | undefined;
632
632
  organizationId?: string | undefined;
633
633
  organizationSlug?: string | undefined;
634
634
  }> & Record<string, any>, Record<string, any> | undefined>>(data_0?: better_auth.Prettify<{
@@ -639,7 +639,7 @@ declare const createClient: (baseUrl?: string) => {
639
639
  sortDirection?: "asc" | "desc" | undefined;
640
640
  filterField?: string | undefined;
641
641
  filterValue?: string | number | boolean | undefined;
642
- filterOperator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "contains" | undefined;
642
+ filterOperator?: "eq" | "ne" | "gt" | "gte" | "lt" | "lte" | "contains" | undefined;
643
643
  organizationId?: string | undefined;
644
644
  organizationSlug?: string | undefined;
645
645
  } | undefined;
@@ -746,7 +746,7 @@ declare const createClient: (baseUrl?: string) => {
746
746
  } & {
747
747
  signIn: {
748
748
  social: <FetchOptions extends better_auth.ClientFetchOption<Partial<{
749
- provider: (string & {}) | "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "huggingface" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linear" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "vercel";
749
+ provider: (string & {}) | "linear" | "huggingface" | "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "vercel";
750
750
  callbackURL?: string | undefined;
751
751
  newUserCallbackURL?: string | undefined;
752
752
  errorCallbackURL?: string | undefined;
@@ -763,7 +763,7 @@ declare const createClient: (baseUrl?: string) => {
763
763
  loginHint?: string | undefined;
764
764
  additionalData?: Record<string, any> | undefined;
765
765
  }> & Record<string, any>, Partial<Record<string, any>> & Record<string, any>, Record<string, any> | undefined>>(data_0: better_auth.Prettify<{
766
- provider: (string & {}) | "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "huggingface" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linear" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "vercel";
766
+ provider: (string & {}) | "linear" | "huggingface" | "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "vercel";
767
767
  callbackURL?: string | undefined;
768
768
  newUserCallbackURL?: string | undefined;
769
769
  errorCallbackURL?: string | undefined;
@@ -2205,7 +2205,7 @@ declare const authClient: {
2205
2205
  sortDirection?: "asc" | "desc" | undefined;
2206
2206
  filterField?: string | undefined;
2207
2207
  filterValue?: string | number | boolean | undefined;
2208
- filterOperator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "contains" | undefined;
2208
+ filterOperator?: "eq" | "ne" | "gt" | "gte" | "lt" | "lte" | "contains" | undefined;
2209
2209
  organizationId?: string | undefined;
2210
2210
  organizationSlug?: string | undefined;
2211
2211
  }> & Record<string, any>, Record<string, any> | undefined>>(data_0?: better_auth.Prettify<{
@@ -2216,7 +2216,7 @@ declare const authClient: {
2216
2216
  sortDirection?: "asc" | "desc" | undefined;
2217
2217
  filterField?: string | undefined;
2218
2218
  filterValue?: string | number | boolean | undefined;
2219
- filterOperator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "contains" | undefined;
2219
+ filterOperator?: "eq" | "ne" | "gt" | "gte" | "lt" | "lte" | "contains" | undefined;
2220
2220
  organizationId?: string | undefined;
2221
2221
  organizationSlug?: string | undefined;
2222
2222
  } | undefined;
@@ -2323,7 +2323,7 @@ declare const authClient: {
2323
2323
  } & {
2324
2324
  signIn: {
2325
2325
  social: <FetchOptions extends better_auth.ClientFetchOption<Partial<{
2326
- provider: (string & {}) | "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "huggingface" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linear" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "vercel";
2326
+ provider: (string & {}) | "linear" | "huggingface" | "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "vercel";
2327
2327
  callbackURL?: string | undefined;
2328
2328
  newUserCallbackURL?: string | undefined;
2329
2329
  errorCallbackURL?: string | undefined;
@@ -2340,7 +2340,7 @@ declare const authClient: {
2340
2340
  loginHint?: string | undefined;
2341
2341
  additionalData?: Record<string, any> | undefined;
2342
2342
  }> & Record<string, any>, Partial<Record<string, any>> & Record<string, any>, Record<string, any> | undefined>>(data_0: better_auth.Prettify<{
2343
- provider: (string & {}) | "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "huggingface" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linear" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "vercel";
2343
+ provider: (string & {}) | "linear" | "huggingface" | "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "vercel";
2344
2344
  callbackURL?: string | undefined;
2345
2345
  newUserCallbackURL?: string | undefined;
2346
2346
  errorCallbackURL?: string | undefined;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { AuthConfig, EmailNormalizationConfig, TurnstileConfig, authMiddleware, createAuth, createAuthApp, getInvitationLink, getSessionToken, isGmailAddress, normalizeEmail, schema, verifyTurnstile } from './backend/index.js';
1
+ export { AuthConfig, EmailNormalizationConfig, FieldAttribute, SchemaMapping, TableMapping, TurnstileConfig, authMiddleware, createAuth, createAuthApp, getInvitationLink, getSessionToken, isGmailAddress, normalizeEmail, schema, verifyTurnstile } from './backend/index.js';
2
2
  export { AuthForm, CreateOrganizationForm, ForgotPasswordForm, InviteMemberForm, OrganizationSwitcher, PasswordChanger, PasswordChangerProps, ProfileEditor, ProfileEditorProps, ResetPasswordForm } from './frontend/index.js';
3
3
  export { authClient, createClient } from './frontend/client.js';
4
4
  export * from 'better-auth';
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  normalizeEmail,
10
10
  schema_exports,
11
11
  verifyTurnstile
12
- } from "./chunk-HTFOOF6M.js";
12
+ } from "./chunk-I7BMKFVZ.js";
13
13
  import {
14
14
  AuthForm,
15
15
  CreateOrganizationForm,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@contentgrowth/content-auth",
3
- "version": "0.3.3",
4
- "description": "Better Auth wrapper with UI components for Cloudflare Workers & Pages. Includes Turnstile bot protection and email normalization.",
3
+ "version": "0.4.0",
4
+ "description": "Better Auth wrapper with UI components for Cloudflare Workers & Pages. Includes custom schema mapping, Turnstile bot protection, and email normalization.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",