@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.
package/dist/backend/index.d.ts
CHANGED
|
@@ -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 };
|
package/dist/backend/index.js
CHANGED
|
@@ -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
|
-
|
|
38
|
-
|
|
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
|
|
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
|
|
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" | "
|
|
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" | "
|
|
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" | "
|
|
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" | "
|
|
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" | "
|
|
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" | "
|
|
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" | "
|
|
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" | "
|
|
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
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentgrowth/content-auth",
|
|
3
|
-
"version": "0.
|
|
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",
|