@contentgrowth/content-auth 0.3.1 → 0.3.3

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.
@@ -9,7 +9,7 @@ import {
9
9
  normalizeEmail,
10
10
  schema_exports,
11
11
  verifyTurnstile
12
- } from "../chunk-H37QRFRH.js";
12
+ } from "../chunk-HTFOOF6M.js";
13
13
  import "../chunk-R5U7XKVJ.js";
14
14
  export {
15
15
  Hono,
@@ -83,7 +83,27 @@ var AuthForm = ({
83
83
  }
84
84
  onSuccess?.(response.data);
85
85
  } catch (err) {
86
- setError(err.message || "An error occurred");
86
+ const errorMessage = err.message || "";
87
+ const errorCode = err.code || "";
88
+ let friendlyMessage = "An error occurred. Please try again.";
89
+ if (errorMessage.includes("TURNSTILE") || errorMessage.includes("security challenge")) {
90
+ friendlyMessage = "Security verification failed. Please complete the challenge and try again.";
91
+ } else if (errorMessage.includes("EMAIL_EXISTS") || errorMessage.includes("already exists")) {
92
+ friendlyMessage = "An account with this email already exists. Try signing in instead.";
93
+ } else if (errorMessage.includes("Invalid email") || errorMessage.includes("invalid email")) {
94
+ friendlyMessage = "Please enter a valid email address.";
95
+ } else if (errorMessage.includes("Invalid password") || errorMessage.includes("incorrect")) {
96
+ friendlyMessage = "Invalid email or password. Please check your credentials.";
97
+ } else if (errorMessage.includes("User not found")) {
98
+ friendlyMessage = "No account found with this email. Try signing up instead.";
99
+ } else if (errorMessage.includes("too short") || errorMessage.includes("password")) {
100
+ friendlyMessage = "Password must be at least 8 characters long.";
101
+ } else if (errorCode === "BAD_REQUEST" || err.status === 400) {
102
+ friendlyMessage = "Please check your information and try again.";
103
+ } else if (err.message) {
104
+ friendlyMessage = err.message;
105
+ }
106
+ setError(friendlyMessage);
87
107
  if (turnstileRef.current) {
88
108
  turnstileRef.current.reset();
89
109
  setTurnstileToken(null);
@@ -4,6 +4,7 @@ import {
4
4
 
5
5
  // src/backend/index.ts
6
6
  import { betterAuth } from "better-auth";
7
+ import { createAuthMiddleware, APIError } from "better-auth/api";
7
8
  import { drizzleAdapter } from "better-auth/adapters/drizzle";
8
9
  import { drizzle } from "drizzle-orm/d1";
9
10
  import { Hono } from "hono";
@@ -318,77 +319,48 @@ var createAuth = (config) => {
318
319
  };
319
320
  }
320
321
  const normalizedEmailColumn = emailNormalization?.columnName || "normalized_email";
321
- const contentAuthHooks = {
322
- before: async (context) => {
323
- const path = context.path || "";
324
- if (path.includes("/sign-up/email")) {
325
- try {
326
- let body;
327
- if (context.body) {
328
- body = context.body;
329
- } else {
330
- try {
331
- body = await context.request.clone().json();
332
- } catch (e) {
333
- }
322
+ const contentAuthBeforeHook = createAuthMiddleware(async (ctx) => {
323
+ const path = ctx.path || "";
324
+ if (path.includes("/sign-up/email")) {
325
+ const body = ctx.body;
326
+ if (body) {
327
+ if (turnstileConfig?.secretKey) {
328
+ const turnstileToken = body.turnstileToken;
329
+ if (!turnstileToken) {
330
+ console.warn("[ContentAuth] Email signup missing Turnstile token");
331
+ throw new APIError("BAD_REQUEST", {
332
+ message: "Please complete the security challenge"
333
+ });
334
334
  }
335
- if (body) {
336
- if (turnstileConfig?.secretKey) {
337
- const turnstileToken = body.turnstileToken;
338
- if (!turnstileToken) {
339
- console.warn("[ContentAuth] Email signup missing Turnstile token");
340
- return {
341
- status: 400,
342
- body: JSON.stringify({
343
- success: false,
344
- code: "TURNSTILE_REQUIRED",
345
- message: "Please complete the security challenge"
346
- }),
347
- headers: { "Content-Type": "application/json" }
348
- };
349
- }
350
- const { success, error } = await verifyTurnstile(turnstileConfig.secretKey, turnstileToken);
351
- if (!success) {
352
- console.warn(`[ContentAuth] Turnstile verification failed: ${error}`);
353
- return {
354
- status: 400,
355
- body: JSON.stringify({
356
- success: false,
357
- code: "TURNSTILE_FAILED",
358
- message: error || "Security challenge failed. Please try again."
359
- }),
360
- headers: { "Content-Type": "application/json" }
361
- };
362
- }
363
- }
364
- if (emailNormalization?.enabled && body.email && rawDb?.prepare) {
365
- const normalized = normalizeEmail(body.email);
366
- const existing = await rawDb.prepare(
367
- `SELECT id FROM users WHERE ${normalizedEmailColumn} = ?`
368
- ).bind(normalized).first();
369
- if (existing) {
370
- console.warn(`[ContentAuth] Duplicate normalized email detected: ${normalized}`);
371
- return {
372
- status: 400,
373
- body: JSON.stringify({
374
- success: false,
375
- code: "EMAIL_EXISTS",
376
- message: "An account with this email already exists"
377
- }),
378
- headers: { "Content-Type": "application/json" }
379
- };
380
- }
381
- }
335
+ const { success, error } = await verifyTurnstile(turnstileConfig.secretKey, turnstileToken);
336
+ if (!success) {
337
+ console.warn(`[ContentAuth] Turnstile verification failed: ${error}`);
338
+ throw new APIError("BAD_REQUEST", {
339
+ message: error || "Security challenge failed. Please try again."
340
+ });
341
+ }
342
+ }
343
+ if (emailNormalization?.enabled && body.email && rawDb?.prepare) {
344
+ const normalized = normalizeEmail(body.email);
345
+ const existing = await rawDb.prepare(
346
+ `SELECT id FROM users WHERE ${normalizedEmailColumn} = ?`
347
+ ).bind(normalized).first();
348
+ if (existing) {
349
+ console.warn(`[ContentAuth] Duplicate normalized email detected: ${normalized}`);
350
+ throw new APIError("BAD_REQUEST", {
351
+ message: "An account with this email already exists"
352
+ });
382
353
  }
383
- } catch (e) {
384
- console.error("[ContentAuth] Email signup hook error:", e.message);
385
354
  }
386
355
  }
387
- if (userHooks?.before) {
388
- return userHooks.before(context);
389
- }
390
- return;
391
- },
356
+ }
357
+ if (userHooks?.before) {
358
+ return userHooks.before(ctx);
359
+ }
360
+ return;
361
+ });
362
+ const contentAuthHooks = {
363
+ before: contentAuthBeforeHook,
392
364
  after: async (context) => {
393
365
  const path = context.path || "";
394
366
  const user = context.user || context.response?.user || context.data?.user || context.context?.returned?.user || context.context?.newSession?.user;
@@ -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" | "gt" | "gte" | "lt" | "lte" | "contains" | undefined;
631
+ filterOperator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "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" | "gt" | "gte" | "lt" | "lte" | "contains" | undefined;
642
+ filterOperator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "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 & {}) | "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";
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";
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 & {}) | "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";
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";
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" | "gt" | "gte" | "lt" | "lte" | "contains" | undefined;
2208
+ filterOperator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "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" | "gt" | "gte" | "lt" | "lte" | "contains" | undefined;
2219
+ filterOperator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "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 & {}) | "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";
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";
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 & {}) | "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";
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";
2344
2344
  callbackURL?: string | undefined;
2345
2345
  newUserCallbackURL?: string | undefined;
2346
2346
  errorCallbackURL?: string | undefined;
@@ -7,7 +7,7 @@ import {
7
7
  PasswordChanger,
8
8
  ProfileEditor,
9
9
  ResetPasswordForm
10
- } from "../chunk-6MYNRK2N.js";
10
+ } from "../chunk-CTASTCWI.js";
11
11
  import {
12
12
  authClient,
13
13
  createClient
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  normalizeEmail,
10
10
  schema_exports,
11
11
  verifyTurnstile
12
- } from "./chunk-H37QRFRH.js";
12
+ } from "./chunk-HTFOOF6M.js";
13
13
  import {
14
14
  AuthForm,
15
15
  CreateOrganizationForm,
@@ -19,7 +19,7 @@ import {
19
19
  PasswordChanger,
20
20
  ProfileEditor,
21
21
  ResetPasswordForm
22
- } from "./chunk-6MYNRK2N.js";
22
+ } from "./chunk-CTASTCWI.js";
23
23
  import {
24
24
  authClient,
25
25
  createClient
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentgrowth/content-auth",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "Better Auth wrapper with UI components for Cloudflare Workers & Pages. Includes Turnstile bot protection and email normalization.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",