authtara-sdk 1.1.20 → 1.1.22

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/react.d.mts CHANGED
@@ -62,10 +62,12 @@ interface AuthTaraAuthProps {
62
62
  onError?: (error: Error) => void;
63
63
  /** Custom API URL for credentials login (defaults to /api/auth/login) */
64
64
  credentialsApiUrl?: string;
65
- /** Custom API URL for registration (defaults to /api/auth/register) */
65
+ /** URL to redirect users for registration */
66
66
  signupUrl?: string;
67
+ /** CloudFlare Turnstile site key (optional - enables CAPTCHA) */
68
+ turnstileSiteKey?: string;
67
69
  }
68
- declare function AuthTaraAuth({ showCredentials, appearance, redirectUrl, onSuccess, onError, credentialsApiUrl, signupUrl, }: AuthTaraAuthProps): react_jsx_runtime.JSX.Element;
70
+ declare function AuthTaraAuth({ showCredentials, appearance, redirectUrl, onSuccess, onError, credentialsApiUrl, signupUrl, turnstileSiteKey, }: AuthTaraAuthProps): react_jsx_runtime.JSX.Element;
69
71
 
70
72
  interface AuthTaraBillingProps {
71
73
  tenantId: string;
package/dist/react.d.ts CHANGED
@@ -62,10 +62,12 @@ interface AuthTaraAuthProps {
62
62
  onError?: (error: Error) => void;
63
63
  /** Custom API URL for credentials login (defaults to /api/auth/login) */
64
64
  credentialsApiUrl?: string;
65
- /** Custom API URL for registration (defaults to /api/auth/register) */
65
+ /** URL to redirect users for registration */
66
66
  signupUrl?: string;
67
+ /** CloudFlare Turnstile site key (optional - enables CAPTCHA) */
68
+ turnstileSiteKey?: string;
67
69
  }
68
- declare function AuthTaraAuth({ showCredentials, appearance, redirectUrl, onSuccess, onError, credentialsApiUrl, signupUrl, }: AuthTaraAuthProps): react_jsx_runtime.JSX.Element;
70
+ declare function AuthTaraAuth({ showCredentials, appearance, redirectUrl, onSuccess, onError, credentialsApiUrl, signupUrl, turnstileSiteKey, }: AuthTaraAuthProps): react_jsx_runtime.JSX.Element;
69
71
 
70
72
  interface AuthTaraBillingProps {
71
73
  tenantId: string;
package/dist/react.js CHANGED
@@ -273,14 +273,44 @@ function AuthTaraAuth({
273
273
  onSuccess,
274
274
  onError,
275
275
  credentialsApiUrl = "/api/auth/login",
276
- signupUrl = "/register"
276
+ signupUrl = "/register",
277
+ turnstileSiteKey
277
278
  }) {
278
279
  const { signIn, isLoading: oauthLoading, user } = useAuth();
279
280
  const [error, setError] = React2.useState(null);
280
281
  const [isCredentialsLoading, setIsCredentialsLoading] = React2.useState(false);
282
+ const [turnstileToken, setTurnstileToken] = React2.useState(null);
283
+ const turnstileContainerRef = React2.useRef(null);
284
+ const turnstileWidgetId = React2.useRef(null);
281
285
  const [email, setEmail] = React2.useState("");
282
286
  const [password, setPassword] = React2.useState("");
283
287
  const isLoading = oauthLoading || isCredentialsLoading;
288
+ const isDark = appearance?.theme === "dark";
289
+ React2.useEffect(() => {
290
+ if (!turnstileSiteKey || !turnstileContainerRef.current) return;
291
+ if (typeof window === "undefined" || !window.turnstile) return;
292
+ if (turnstileWidgetId.current) return;
293
+ const widgetId = window.turnstile.render(turnstileContainerRef.current, {
294
+ sitekey: turnstileSiteKey,
295
+ theme: isDark ? "dark" : "light",
296
+ callback: (token) => setTurnstileToken(token),
297
+ "expired-callback": () => setTurnstileToken(null),
298
+ "error-callback": () => setTurnstileToken(null)
299
+ });
300
+ turnstileWidgetId.current = widgetId;
301
+ return () => {
302
+ if (turnstileWidgetId.current && window.turnstile) {
303
+ window.turnstile.remove(turnstileWidgetId.current);
304
+ turnstileWidgetId.current = null;
305
+ }
306
+ };
307
+ }, [turnstileSiteKey, isDark]);
308
+ function resetTurnstile() {
309
+ if (turnstileWidgetId.current && window.turnstile) {
310
+ window.turnstile.reset(turnstileWidgetId.current);
311
+ setTurnstileToken(null);
312
+ }
313
+ }
284
314
  async function handleOAuthSignIn(selectedProvider) {
285
315
  setError(null);
286
316
  try {
@@ -303,6 +333,9 @@ function AuthTaraAuth({
303
333
  if (!email || !password) {
304
334
  throw new Error("Email and password are required");
305
335
  }
336
+ if (turnstileSiteKey && !turnstileToken) {
337
+ throw new Error("Please complete the CAPTCHA verification");
338
+ }
306
339
  const response = await fetch(credentialsApiUrl, {
307
340
  method: "POST",
308
341
  headers: { "Content-Type": "application/json" },
@@ -310,7 +343,8 @@ function AuthTaraAuth({
310
343
  body: JSON.stringify({
311
344
  email,
312
345
  password,
313
- redirectUrl
346
+ redirectUrl,
347
+ turnstileToken: turnstileToken || void 0
314
348
  })
315
349
  });
316
350
  const result = await response.json();
@@ -325,11 +359,11 @@ function AuthTaraAuth({
325
359
  const message = err instanceof Error ? err.message : "Authentication failed";
326
360
  setError(message);
327
361
  onError?.(err);
362
+ resetTurnstile();
328
363
  } finally {
329
364
  setIsCredentialsLoading(false);
330
365
  }
331
366
  }
332
- const isDark = appearance?.theme === "dark";
333
367
  const cardBgColor = isDark ? "#111111" : "#ffffff";
334
368
  const cardBorderColor = isDark ? "#222222" : "#e5e7eb";
335
369
  const textColor = isDark ? "#ffffff" : "#111827";
@@ -544,11 +578,12 @@ function AuthTaraAuth({
544
578
  }
545
579
  )
546
580
  ] }),
581
+ turnstileSiteKey && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", justifyContent: "center", marginTop: "0.5rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ref: turnstileContainerRef }) }),
547
582
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
548
583
  "button",
549
584
  {
550
585
  type: "submit",
551
- disabled: isLoading,
586
+ disabled: isLoading || (turnstileSiteKey ? !turnstileToken : false),
552
587
  style: {
553
588
  width: "100%",
554
589
  padding: "0.875rem 1rem",
@@ -558,8 +593,8 @@ function AuthTaraAuth({
558
593
  color: primaryBtnText,
559
594
  fontSize: "0.9375rem",
560
595
  fontWeight: "700",
561
- cursor: isLoading ? "not-allowed" : "pointer",
562
- opacity: isLoading ? 0.7 : 1,
596
+ cursor: isLoading || turnstileSiteKey && !turnstileToken ? "not-allowed" : "pointer",
597
+ opacity: isLoading || turnstileSiteKey && !turnstileToken ? 0.7 : 1,
563
598
  transition: "all 0.15s ease-in-out",
564
599
  marginTop: "0.5rem"
565
600
  },
package/dist/react.mjs CHANGED
@@ -237,14 +237,44 @@ function AuthTaraAuth({
237
237
  onSuccess,
238
238
  onError,
239
239
  credentialsApiUrl = "/api/auth/login",
240
- signupUrl = "/register"
240
+ signupUrl = "/register",
241
+ turnstileSiteKey
241
242
  }) {
242
243
  const { signIn, isLoading: oauthLoading, user } = useAuth();
243
244
  const [error, setError] = React2.useState(null);
244
245
  const [isCredentialsLoading, setIsCredentialsLoading] = React2.useState(false);
246
+ const [turnstileToken, setTurnstileToken] = React2.useState(null);
247
+ const turnstileContainerRef = React2.useRef(null);
248
+ const turnstileWidgetId = React2.useRef(null);
245
249
  const [email, setEmail] = React2.useState("");
246
250
  const [password, setPassword] = React2.useState("");
247
251
  const isLoading = oauthLoading || isCredentialsLoading;
252
+ const isDark = appearance?.theme === "dark";
253
+ React2.useEffect(() => {
254
+ if (!turnstileSiteKey || !turnstileContainerRef.current) return;
255
+ if (typeof window === "undefined" || !window.turnstile) return;
256
+ if (turnstileWidgetId.current) return;
257
+ const widgetId = window.turnstile.render(turnstileContainerRef.current, {
258
+ sitekey: turnstileSiteKey,
259
+ theme: isDark ? "dark" : "light",
260
+ callback: (token) => setTurnstileToken(token),
261
+ "expired-callback": () => setTurnstileToken(null),
262
+ "error-callback": () => setTurnstileToken(null)
263
+ });
264
+ turnstileWidgetId.current = widgetId;
265
+ return () => {
266
+ if (turnstileWidgetId.current && window.turnstile) {
267
+ window.turnstile.remove(turnstileWidgetId.current);
268
+ turnstileWidgetId.current = null;
269
+ }
270
+ };
271
+ }, [turnstileSiteKey, isDark]);
272
+ function resetTurnstile() {
273
+ if (turnstileWidgetId.current && window.turnstile) {
274
+ window.turnstile.reset(turnstileWidgetId.current);
275
+ setTurnstileToken(null);
276
+ }
277
+ }
248
278
  async function handleOAuthSignIn(selectedProvider) {
249
279
  setError(null);
250
280
  try {
@@ -267,6 +297,9 @@ function AuthTaraAuth({
267
297
  if (!email || !password) {
268
298
  throw new Error("Email and password are required");
269
299
  }
300
+ if (turnstileSiteKey && !turnstileToken) {
301
+ throw new Error("Please complete the CAPTCHA verification");
302
+ }
270
303
  const response = await fetch(credentialsApiUrl, {
271
304
  method: "POST",
272
305
  headers: { "Content-Type": "application/json" },
@@ -274,7 +307,8 @@ function AuthTaraAuth({
274
307
  body: JSON.stringify({
275
308
  email,
276
309
  password,
277
- redirectUrl
310
+ redirectUrl,
311
+ turnstileToken: turnstileToken || void 0
278
312
  })
279
313
  });
280
314
  const result = await response.json();
@@ -289,11 +323,11 @@ function AuthTaraAuth({
289
323
  const message = err instanceof Error ? err.message : "Authentication failed";
290
324
  setError(message);
291
325
  onError?.(err);
326
+ resetTurnstile();
292
327
  } finally {
293
328
  setIsCredentialsLoading(false);
294
329
  }
295
330
  }
296
- const isDark = appearance?.theme === "dark";
297
331
  const cardBgColor = isDark ? "#111111" : "#ffffff";
298
332
  const cardBorderColor = isDark ? "#222222" : "#e5e7eb";
299
333
  const textColor = isDark ? "#ffffff" : "#111827";
@@ -508,11 +542,12 @@ function AuthTaraAuth({
508
542
  }
509
543
  )
510
544
  ] }),
545
+ turnstileSiteKey && /* @__PURE__ */ jsx2("div", { style: { display: "flex", justifyContent: "center", marginTop: "0.5rem" }, children: /* @__PURE__ */ jsx2("div", { ref: turnstileContainerRef }) }),
511
546
  /* @__PURE__ */ jsx2(
512
547
  "button",
513
548
  {
514
549
  type: "submit",
515
- disabled: isLoading,
550
+ disabled: isLoading || (turnstileSiteKey ? !turnstileToken : false),
516
551
  style: {
517
552
  width: "100%",
518
553
  padding: "0.875rem 1rem",
@@ -522,8 +557,8 @@ function AuthTaraAuth({
522
557
  color: primaryBtnText,
523
558
  fontSize: "0.9375rem",
524
559
  fontWeight: "700",
525
- cursor: isLoading ? "not-allowed" : "pointer",
526
- opacity: isLoading ? 0.7 : 1,
560
+ cursor: isLoading || turnstileSiteKey && !turnstileToken ? "not-allowed" : "pointer",
561
+ opacity: isLoading || turnstileSiteKey && !turnstileToken ? 0.7 : 1,
527
562
  transition: "all 0.15s ease-in-out",
528
563
  marginTop: "0.5rem"
529
564
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "authtara-sdk",
3
- "version": "1.1.20",
3
+ "version": "1.1.22",
4
4
  "description": "SDK Client untuk integrasi dengan DigitalSolution Platform - SSO, Billing, dan Metering",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",