@sparkstudio/authentication-ui 1.0.5 → 1.0.6

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/index.cjs CHANGED
@@ -20,7 +20,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- AuthenticationTestButton: () => AuthenticationTestButton,
24
23
  AuthenticatorProvider: () => AuthenticatorProvider,
25
24
  EMPTY_GUID: () => EMPTY_GUID,
26
25
  LoginButton: () => LoginButton,
@@ -34,14 +33,6 @@ module.exports = __toCommonJS(index_exports);
34
33
  // src/context/UserProvider.tsx
35
34
  var import_react = require("react");
36
35
 
37
- // src/AppSettings.ts
38
- var AppSettings = {
39
- APIUrl: "https://localhost:5001",
40
- Version: "1.0.0",
41
- GoogleClientId: "317399248822-u2seld36hjot7nf2p24oe3icm01aok51.apps.googleusercontent.com",
42
- ApplicationName: "3D Crate"
43
- };
44
-
45
36
  // src/api/Controllers/Auth.ts
46
37
  var Auth = class {
47
38
  baseUrl;
@@ -111,34 +102,50 @@ var SparkStudioAuthenticationSDK = class {
111
102
  // src/context/UserProvider.tsx
112
103
  var import_jsx_runtime = require("react/jsx-runtime");
113
104
  var UserContext = (0, import_react.createContext)(void 0);
114
- function UserProvider({ children }) {
105
+ function UserProvider({
106
+ children,
107
+ apiUrl,
108
+ onLoginSuccess,
109
+ onLoginFailed,
110
+ onLogoutSuccess,
111
+ onLogoutFailed
112
+ }) {
115
113
  const [user, setUserState] = (0, import_react.useState)(null);
116
114
  (0, import_react.useEffect)(() => {
117
115
  const fetchUser = async () => {
118
116
  try {
119
- const api = new SparkStudioAuthenticationSDK(AppSettings.APIUrl);
117
+ const api = new SparkStudioAuthenticationSDK(apiUrl);
120
118
  const me = await api.auth.GetCurrentUser();
121
- setUserState(me);
119
+ setUser(me);
122
120
  } catch (error) {
123
121
  console.warn("No user logged in", error);
124
122
  setUserState(null);
123
+ onLoginFailed?.(error);
125
124
  }
126
125
  };
127
126
  fetchUser();
128
- }, []);
127
+ }, [apiUrl]);
129
128
  const setUser = (user2) => {
130
129
  setUserState(user2);
130
+ if (user2) {
131
+ onLoginSuccess?.(user2);
132
+ }
131
133
  };
132
134
  const logout = async () => {
133
135
  try {
134
- const api = new SparkStudioAuthenticationSDK(AppSettings.APIUrl);
136
+ const api = new SparkStudioAuthenticationSDK(apiUrl);
135
137
  await api.auth.Logout?.();
138
+ onLogoutSuccess?.();
136
139
  } catch (err) {
137
- console.warn("Logout failed (server side), clearing client state anyway", err);
140
+ console.warn(
141
+ "Logout failed (server side), clearing client state anyway",
142
+ err
143
+ );
144
+ onLogoutFailed?.(err);
138
145
  }
139
146
  setUserState(null);
140
147
  };
141
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UserContext.Provider, { value: { user, setUser, logout }, children });
148
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(UserContext.Provider, { value: { user, setUser, logout, apiUrl }, children });
142
149
  }
143
150
  function useUser() {
144
151
  const context = (0, import_react.useContext)(UserContext);
@@ -151,27 +158,35 @@ var import_react2 = require("react");
151
158
  var import_google = require("@react-oauth/google");
152
159
  var import_common_ui = require("@sparkstudio/common-ui");
153
160
  var import_jsx_runtime2 = require("react/jsx-runtime");
154
- function LoginButton({ onSuccess }) {
155
- const { setUser } = useUser();
161
+ function LoginButton({ onLogin, onLoginFailed }) {
162
+ const { setUser, apiUrl } = useUser();
156
163
  const [loading, setLoading] = (0, import_react2.useState)(false);
157
164
  const login = (0, import_google.useGoogleLogin)({
158
165
  flow: "implicit",
159
166
  onSuccess: async (tokenResponse) => {
160
167
  try {
161
- const api = new SparkStudioAuthenticationSDK(AppSettings.APIUrl);
168
+ const api = new SparkStudioAuthenticationSDK(apiUrl);
162
169
  const authentication = await api.auth.SignIn({
163
170
  Token: tokenResponse.access_token
164
171
  });
165
- setUser(authentication?.User ?? null);
166
- onSuccess?.(tokenResponse);
172
+ const user = authentication?.User ?? null;
173
+ setUser(user);
174
+ onLogin?.(user);
167
175
  } catch (error) {
168
176
  console.error("\u{1F534} Login failed (Google or backend SignIn)", error);
177
+ onLoginFailed?.(error);
169
178
  } finally {
170
179
  setLoading(false);
171
180
  }
172
181
  },
173
182
  onError: (error) => {
174
- console.error("\u274C Google Login Failed", error);
183
+ console.error("\u274C Google OAuth Login Failed", error);
184
+ onLoginFailed?.(error);
185
+ setLoading(false);
186
+ },
187
+ onNonOAuthError: (nonOAuthError) => {
188
+ console.error("\u26A0\uFE0F Google Non-OAuth error", nonOAuthError);
189
+ onLoginFailed?.(nonOAuthError);
175
190
  setLoading(false);
176
191
  }
177
192
  });
@@ -182,6 +197,7 @@ function LoginButton({ onSuccess }) {
182
197
  login();
183
198
  } catch (err) {
184
199
  console.error("Error starting Google login", err);
200
+ onLoginFailed?.(err);
185
201
  setLoading(false);
186
202
  }
187
203
  };
@@ -199,7 +215,7 @@ function LoginButton({ onSuccess }) {
199
215
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
200
216
  "img",
201
217
  {
202
- src: "../../assets/icons/google_icon.webp",
218
+ src: "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3c/Google_Favicon_2025.svg/960px-Google_Favicon_2025.svg.png",
203
219
  alt: "Google",
204
220
  style: { width: "21px", height: "21px", margin: 0, padding: 0 }
205
221
  }
@@ -211,14 +227,22 @@ function LoginButton({ onSuccess }) {
211
227
  // src/components/UserInfoCard.tsx
212
228
  var import_common_ui2 = require("@sparkstudio/common-ui");
213
229
  var import_jsx_runtime3 = require("react/jsx-runtime");
214
- function UserInfoCard() {
230
+ function UserInfoCard({ onLogin, onLogout, onLoginFailed }) {
215
231
  const { user, logout } = useUser();
232
+ const handleLogout = async () => {
233
+ try {
234
+ await logout();
235
+ onLogout?.();
236
+ } catch (err) {
237
+ console.error("Logout failed", err);
238
+ }
239
+ };
216
240
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children: user ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
217
241
  import_common_ui2.Button,
218
242
  {
219
243
  loadingText: "Logging out...",
220
244
  showSpinner: true,
221
- onAction: () => logout(),
245
+ onAction: handleLogout,
222
246
  renderContent: () => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
223
247
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
224
248
  "img",
@@ -242,7 +266,13 @@ function UserInfoCard() {
242
266
  "Logging out..."
243
267
  ] })
244
268
  }
245
- ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LoginButton, {}) });
269
+ ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
270
+ LoginButton,
271
+ {
272
+ onLogin,
273
+ onLoginFailed
274
+ }
275
+ ) });
246
276
  }
247
277
 
248
278
  // src/components/AuthenticatorProvider.tsx
@@ -250,23 +280,30 @@ var import_google2 = require("@react-oauth/google");
250
280
  var import_jsx_runtime4 = require("react/jsx-runtime");
251
281
  function AuthenticatorProvider({
252
282
  googleClientId,
253
- children
283
+ apiUrl,
284
+ children,
285
+ onLoginSuccess,
286
+ onLoginFailed,
287
+ onLogoutSuccess,
288
+ onLogoutFailed
254
289
  }) {
255
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_google2.GoogleOAuthProvider, { clientId: googleClientId, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(UserProvider, { children }) });
256
- }
257
-
258
- // src/components/Buttons/AuthenticationTestButton.tsx
259
- var import_common_ui3 = require("@sparkstudio/common-ui");
260
- var import_jsx_runtime5 = require("react/jsx-runtime");
261
- function AuthenticationTestButton({ onSuccess }) {
262
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_common_ui3.Button, {});
290
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_google2.GoogleOAuthProvider, { clientId: googleClientId, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
291
+ UserProvider,
292
+ {
293
+ apiUrl,
294
+ onLoginSuccess,
295
+ onLoginFailed,
296
+ onLogoutSuccess,
297
+ onLogoutFailed,
298
+ children
299
+ }
300
+ ) });
263
301
  }
264
302
 
265
303
  // src/types/Guid.ts
266
304
  var EMPTY_GUID = "00000000-0000-0000-0000-000000000000";
267
305
  // Annotate the CommonJS export names for ESM import in node:
268
306
  0 && (module.exports = {
269
- AuthenticationTestButton,
270
307
  AuthenticatorProvider,
271
308
  EMPTY_GUID,
272
309
  LoginButton,
package/dist/index.d.cts CHANGED
@@ -1,28 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
3
 
4
- declare function UserInfoCard(): react_jsx_runtime.JSX.Element;
5
-
6
- interface AuthenticatorProviderProps {
7
- googleClientId: string;
8
- children: ReactNode;
9
- }
10
- /**
11
- * Public entrypoint for consumers:
12
- * Wraps children with Google OAuth + User context.
13
- */
14
- declare function AuthenticatorProvider({ googleClientId, children, }: AuthenticatorProviderProps): react_jsx_runtime.JSX.Element;
15
-
16
- interface LoginButtonProps {
17
- onSuccess?: (tokenResponse: any) => void;
18
- }
19
- declare function LoginButton({ onSuccess }: LoginButtonProps): react_jsx_runtime.JSX.Element;
20
-
21
- interface AuthenticationTestButtonProps {
22
- onSuccess?: (tokenResponse: any) => void;
23
- }
24
- declare function AuthenticationTestButton({ onSuccess }: AuthenticationTestButtonProps): react_jsx_runtime.JSX.Element;
25
-
26
4
  /**
27
5
  * Represents an Auto-generated model for UserDTO.
28
6
  */
@@ -41,15 +19,61 @@ declare class UserDTO implements IUserDTO {
41
19
  constructor(init: UserDTOInit);
42
20
  }
43
21
 
22
+ interface UserInfoCardProps {
23
+ onLogin?: (user: UserDTO) => void;
24
+ onLoginFailed?: (error: string) => void;
25
+ onLogout?: () => void;
26
+ }
27
+ declare function UserInfoCard({ onLogin, onLogout, onLoginFailed }: UserInfoCardProps): react_jsx_runtime.JSX.Element;
28
+
29
+ interface AuthenticatorProviderProps {
30
+ googleClientId: string;
31
+ apiUrl: string;
32
+ children: ReactNode;
33
+ onLoginSuccess?: (user: UserDTO | null) => void;
34
+ onLoginFailed?: (error: unknown) => void;
35
+ onLogoutSuccess?: () => void;
36
+ onLogoutFailed?: (error: unknown) => void;
37
+ }
38
+ /**
39
+ * Public entrypoint for consumers:
40
+ * Wraps children with Google OAuth + User context.
41
+ */
42
+ declare function AuthenticatorProvider({ googleClientId, apiUrl, children, onLoginSuccess, onLoginFailed, onLogoutSuccess, onLogoutFailed, }: AuthenticatorProviderProps): react_jsx_runtime.JSX.Element;
43
+
44
+ /**
45
+ * Represents an Auto-generated model for AuthResponse.
46
+ */
47
+ interface IAuthResponse {
48
+ User: UserDTO;
49
+ }
50
+ type AuthResponseInit = Partial<IAuthResponse> & Pick<IAuthResponse, "User">;
51
+ declare class AuthResponse implements IAuthResponse {
52
+ User: UserDTO;
53
+ constructor(init: AuthResponseInit);
54
+ }
55
+
56
+ interface LoginButtonProps {
57
+ onLogin?: (user: AuthResponse["User"]) => void;
58
+ onLoginFailed?: (error: any) => void;
59
+ }
60
+ declare function LoginButton({ onLogin, onLoginFailed }: LoginButtonProps): react_jsx_runtime.JSX.Element;
61
+
44
62
  interface UserContextType {
45
63
  user: UserDTO | null;
46
64
  setUser: (user: UserDTO | null) => void;
47
65
  logout: () => Promise<void>;
66
+ apiUrl: string;
48
67
  }
49
68
  interface UserProviderProps {
50
69
  children: ReactNode;
70
+ apiUrl: string;
71
+ onLoginSuccess?: (user: UserDTO | null) => void;
72
+ onLoginFailed?: (error: unknown) => void;
73
+ onLogoutSuccess?: () => void;
74
+ onLogoutFailed?: (error: unknown) => void;
51
75
  }
52
- declare function UserProvider({ children }: UserProviderProps): react_jsx_runtime.JSX.Element;
76
+ declare function UserProvider({ children, apiUrl, onLoginSuccess, onLoginFailed, onLogoutSuccess, onLogoutFailed, }: UserProviderProps): react_jsx_runtime.JSX.Element;
53
77
  declare function useUser(): UserContextType;
54
78
 
55
79
  type Guid = string;
@@ -67,18 +91,6 @@ declare class TokenRequest implements ITokenRequest {
67
91
  constructor(init: TokenRequestInit);
68
92
  }
69
93
 
70
- /**
71
- * Represents an Auto-generated model for AuthResponse.
72
- */
73
- interface IAuthResponse {
74
- User: UserDTO;
75
- }
76
- type AuthResponseInit = Partial<IAuthResponse> & Pick<IAuthResponse, "User">;
77
- declare class AuthResponse implements IAuthResponse {
78
- User: UserDTO;
79
- constructor(init: AuthResponseInit);
80
- }
81
-
82
94
  /**
83
95
  * Auto-generated client for the Auth controller.
84
96
  */
@@ -107,4 +119,4 @@ declare class SparkStudioAuthenticationSDK {
107
119
  constructor(baseUrl: string);
108
120
  }
109
121
 
110
- export { AuthenticationTestButton, AuthenticatorProvider, type AuthenticatorProviderProps, EMPTY_GUID, type Guid, LoginButton, SparkStudioAuthenticationSDK, UserInfoCard, UserProvider, useUser };
122
+ export { AuthenticatorProvider, type AuthenticatorProviderProps, EMPTY_GUID, type Guid, LoginButton, SparkStudioAuthenticationSDK, UserInfoCard, UserProvider, useUser };
package/dist/index.d.ts CHANGED
@@ -1,28 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
3
 
4
- declare function UserInfoCard(): react_jsx_runtime.JSX.Element;
5
-
6
- interface AuthenticatorProviderProps {
7
- googleClientId: string;
8
- children: ReactNode;
9
- }
10
- /**
11
- * Public entrypoint for consumers:
12
- * Wraps children with Google OAuth + User context.
13
- */
14
- declare function AuthenticatorProvider({ googleClientId, children, }: AuthenticatorProviderProps): react_jsx_runtime.JSX.Element;
15
-
16
- interface LoginButtonProps {
17
- onSuccess?: (tokenResponse: any) => void;
18
- }
19
- declare function LoginButton({ onSuccess }: LoginButtonProps): react_jsx_runtime.JSX.Element;
20
-
21
- interface AuthenticationTestButtonProps {
22
- onSuccess?: (tokenResponse: any) => void;
23
- }
24
- declare function AuthenticationTestButton({ onSuccess }: AuthenticationTestButtonProps): react_jsx_runtime.JSX.Element;
25
-
26
4
  /**
27
5
  * Represents an Auto-generated model for UserDTO.
28
6
  */
@@ -41,15 +19,61 @@ declare class UserDTO implements IUserDTO {
41
19
  constructor(init: UserDTOInit);
42
20
  }
43
21
 
22
+ interface UserInfoCardProps {
23
+ onLogin?: (user: UserDTO) => void;
24
+ onLoginFailed?: (error: string) => void;
25
+ onLogout?: () => void;
26
+ }
27
+ declare function UserInfoCard({ onLogin, onLogout, onLoginFailed }: UserInfoCardProps): react_jsx_runtime.JSX.Element;
28
+
29
+ interface AuthenticatorProviderProps {
30
+ googleClientId: string;
31
+ apiUrl: string;
32
+ children: ReactNode;
33
+ onLoginSuccess?: (user: UserDTO | null) => void;
34
+ onLoginFailed?: (error: unknown) => void;
35
+ onLogoutSuccess?: () => void;
36
+ onLogoutFailed?: (error: unknown) => void;
37
+ }
38
+ /**
39
+ * Public entrypoint for consumers:
40
+ * Wraps children with Google OAuth + User context.
41
+ */
42
+ declare function AuthenticatorProvider({ googleClientId, apiUrl, children, onLoginSuccess, onLoginFailed, onLogoutSuccess, onLogoutFailed, }: AuthenticatorProviderProps): react_jsx_runtime.JSX.Element;
43
+
44
+ /**
45
+ * Represents an Auto-generated model for AuthResponse.
46
+ */
47
+ interface IAuthResponse {
48
+ User: UserDTO;
49
+ }
50
+ type AuthResponseInit = Partial<IAuthResponse> & Pick<IAuthResponse, "User">;
51
+ declare class AuthResponse implements IAuthResponse {
52
+ User: UserDTO;
53
+ constructor(init: AuthResponseInit);
54
+ }
55
+
56
+ interface LoginButtonProps {
57
+ onLogin?: (user: AuthResponse["User"]) => void;
58
+ onLoginFailed?: (error: any) => void;
59
+ }
60
+ declare function LoginButton({ onLogin, onLoginFailed }: LoginButtonProps): react_jsx_runtime.JSX.Element;
61
+
44
62
  interface UserContextType {
45
63
  user: UserDTO | null;
46
64
  setUser: (user: UserDTO | null) => void;
47
65
  logout: () => Promise<void>;
66
+ apiUrl: string;
48
67
  }
49
68
  interface UserProviderProps {
50
69
  children: ReactNode;
70
+ apiUrl: string;
71
+ onLoginSuccess?: (user: UserDTO | null) => void;
72
+ onLoginFailed?: (error: unknown) => void;
73
+ onLogoutSuccess?: () => void;
74
+ onLogoutFailed?: (error: unknown) => void;
51
75
  }
52
- declare function UserProvider({ children }: UserProviderProps): react_jsx_runtime.JSX.Element;
76
+ declare function UserProvider({ children, apiUrl, onLoginSuccess, onLoginFailed, onLogoutSuccess, onLogoutFailed, }: UserProviderProps): react_jsx_runtime.JSX.Element;
53
77
  declare function useUser(): UserContextType;
54
78
 
55
79
  type Guid = string;
@@ -67,18 +91,6 @@ declare class TokenRequest implements ITokenRequest {
67
91
  constructor(init: TokenRequestInit);
68
92
  }
69
93
 
70
- /**
71
- * Represents an Auto-generated model for AuthResponse.
72
- */
73
- interface IAuthResponse {
74
- User: UserDTO;
75
- }
76
- type AuthResponseInit = Partial<IAuthResponse> & Pick<IAuthResponse, "User">;
77
- declare class AuthResponse implements IAuthResponse {
78
- User: UserDTO;
79
- constructor(init: AuthResponseInit);
80
- }
81
-
82
94
  /**
83
95
  * Auto-generated client for the Auth controller.
84
96
  */
@@ -107,4 +119,4 @@ declare class SparkStudioAuthenticationSDK {
107
119
  constructor(baseUrl: string);
108
120
  }
109
121
 
110
- export { AuthenticationTestButton, AuthenticatorProvider, type AuthenticatorProviderProps, EMPTY_GUID, type Guid, LoginButton, SparkStudioAuthenticationSDK, UserInfoCard, UserProvider, useUser };
122
+ export { AuthenticatorProvider, type AuthenticatorProviderProps, EMPTY_GUID, type Guid, LoginButton, SparkStudioAuthenticationSDK, UserInfoCard, UserProvider, useUser };
package/dist/index.js CHANGED
@@ -1,13 +1,10 @@
1
1
  // src/context/UserProvider.tsx
2
- import { createContext, useContext, useState, useEffect } from "react";
3
-
4
- // src/AppSettings.ts
5
- var AppSettings = {
6
- APIUrl: "https://localhost:5001",
7
- Version: "1.0.0",
8
- GoogleClientId: "317399248822-u2seld36hjot7nf2p24oe3icm01aok51.apps.googleusercontent.com",
9
- ApplicationName: "3D Crate"
10
- };
2
+ import {
3
+ createContext,
4
+ useContext,
5
+ useState,
6
+ useEffect
7
+ } from "react";
11
8
 
12
9
  // src/api/Controllers/Auth.ts
13
10
  var Auth = class {
@@ -78,34 +75,50 @@ var SparkStudioAuthenticationSDK = class {
78
75
  // src/context/UserProvider.tsx
79
76
  import { jsx } from "react/jsx-runtime";
80
77
  var UserContext = createContext(void 0);
81
- function UserProvider({ children }) {
78
+ function UserProvider({
79
+ children,
80
+ apiUrl,
81
+ onLoginSuccess,
82
+ onLoginFailed,
83
+ onLogoutSuccess,
84
+ onLogoutFailed
85
+ }) {
82
86
  const [user, setUserState] = useState(null);
83
87
  useEffect(() => {
84
88
  const fetchUser = async () => {
85
89
  try {
86
- const api = new SparkStudioAuthenticationSDK(AppSettings.APIUrl);
90
+ const api = new SparkStudioAuthenticationSDK(apiUrl);
87
91
  const me = await api.auth.GetCurrentUser();
88
- setUserState(me);
92
+ setUser(me);
89
93
  } catch (error) {
90
94
  console.warn("No user logged in", error);
91
95
  setUserState(null);
96
+ onLoginFailed?.(error);
92
97
  }
93
98
  };
94
99
  fetchUser();
95
- }, []);
100
+ }, [apiUrl]);
96
101
  const setUser = (user2) => {
97
102
  setUserState(user2);
103
+ if (user2) {
104
+ onLoginSuccess?.(user2);
105
+ }
98
106
  };
99
107
  const logout = async () => {
100
108
  try {
101
- const api = new SparkStudioAuthenticationSDK(AppSettings.APIUrl);
109
+ const api = new SparkStudioAuthenticationSDK(apiUrl);
102
110
  await api.auth.Logout?.();
111
+ onLogoutSuccess?.();
103
112
  } catch (err) {
104
- console.warn("Logout failed (server side), clearing client state anyway", err);
113
+ console.warn(
114
+ "Logout failed (server side), clearing client state anyway",
115
+ err
116
+ );
117
+ onLogoutFailed?.(err);
105
118
  }
106
119
  setUserState(null);
107
120
  };
108
- return /* @__PURE__ */ jsx(UserContext.Provider, { value: { user, setUser, logout }, children });
121
+ return /* @__PURE__ */ jsx(UserContext.Provider, { value: { user, setUser, logout, apiUrl }, children });
109
122
  }
110
123
  function useUser() {
111
124
  const context = useContext(UserContext);
@@ -118,27 +131,35 @@ import { useState as useState2 } from "react";
118
131
  import { useGoogleLogin } from "@react-oauth/google";
119
132
  import { Button } from "@sparkstudio/common-ui";
120
133
  import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
121
- function LoginButton({ onSuccess }) {
122
- const { setUser } = useUser();
134
+ function LoginButton({ onLogin, onLoginFailed }) {
135
+ const { setUser, apiUrl } = useUser();
123
136
  const [loading, setLoading] = useState2(false);
124
137
  const login = useGoogleLogin({
125
138
  flow: "implicit",
126
139
  onSuccess: async (tokenResponse) => {
127
140
  try {
128
- const api = new SparkStudioAuthenticationSDK(AppSettings.APIUrl);
141
+ const api = new SparkStudioAuthenticationSDK(apiUrl);
129
142
  const authentication = await api.auth.SignIn({
130
143
  Token: tokenResponse.access_token
131
144
  });
132
- setUser(authentication?.User ?? null);
133
- onSuccess?.(tokenResponse);
145
+ const user = authentication?.User ?? null;
146
+ setUser(user);
147
+ onLogin?.(user);
134
148
  } catch (error) {
135
149
  console.error("\u{1F534} Login failed (Google or backend SignIn)", error);
150
+ onLoginFailed?.(error);
136
151
  } finally {
137
152
  setLoading(false);
138
153
  }
139
154
  },
140
155
  onError: (error) => {
141
- console.error("\u274C Google Login Failed", error);
156
+ console.error("\u274C Google OAuth Login Failed", error);
157
+ onLoginFailed?.(error);
158
+ setLoading(false);
159
+ },
160
+ onNonOAuthError: (nonOAuthError) => {
161
+ console.error("\u26A0\uFE0F Google Non-OAuth error", nonOAuthError);
162
+ onLoginFailed?.(nonOAuthError);
142
163
  setLoading(false);
143
164
  }
144
165
  });
@@ -149,6 +170,7 @@ function LoginButton({ onSuccess }) {
149
170
  login();
150
171
  } catch (err) {
151
172
  console.error("Error starting Google login", err);
173
+ onLoginFailed?.(err);
152
174
  setLoading(false);
153
175
  }
154
176
  };
@@ -166,7 +188,7 @@ function LoginButton({ onSuccess }) {
166
188
  /* @__PURE__ */ jsx2(
167
189
  "img",
168
190
  {
169
- src: "../../assets/icons/google_icon.webp",
191
+ src: "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3c/Google_Favicon_2025.svg/960px-Google_Favicon_2025.svg.png",
170
192
  alt: "Google",
171
193
  style: { width: "21px", height: "21px", margin: 0, padding: 0 }
172
194
  }
@@ -178,14 +200,22 @@ function LoginButton({ onSuccess }) {
178
200
  // src/components/UserInfoCard.tsx
179
201
  import { Button as Button2 } from "@sparkstudio/common-ui";
180
202
  import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
181
- function UserInfoCard() {
203
+ function UserInfoCard({ onLogin, onLogout, onLoginFailed }) {
182
204
  const { user, logout } = useUser();
205
+ const handleLogout = async () => {
206
+ try {
207
+ await logout();
208
+ onLogout?.();
209
+ } catch (err) {
210
+ console.error("Logout failed", err);
211
+ }
212
+ };
183
213
  return /* @__PURE__ */ jsx3(Fragment2, { children: user ? /* @__PURE__ */ jsx3(
184
214
  Button2,
185
215
  {
186
216
  loadingText: "Logging out...",
187
217
  showSpinner: true,
188
- onAction: () => logout(),
218
+ onAction: handleLogout,
189
219
  renderContent: () => /* @__PURE__ */ jsxs2(Fragment2, { children: [
190
220
  /* @__PURE__ */ jsx3(
191
221
  "img",
@@ -209,7 +239,13 @@ function UserInfoCard() {
209
239
  "Logging out..."
210
240
  ] })
211
241
  }
212
- ) : /* @__PURE__ */ jsx3(LoginButton, {}) });
242
+ ) : /* @__PURE__ */ jsx3(
243
+ LoginButton,
244
+ {
245
+ onLogin,
246
+ onLoginFailed
247
+ }
248
+ ) });
213
249
  }
214
250
 
215
251
  // src/components/AuthenticatorProvider.tsx
@@ -217,22 +253,29 @@ import { GoogleOAuthProvider } from "@react-oauth/google";
217
253
  import { jsx as jsx4 } from "react/jsx-runtime";
218
254
  function AuthenticatorProvider({
219
255
  googleClientId,
220
- children
256
+ apiUrl,
257
+ children,
258
+ onLoginSuccess,
259
+ onLoginFailed,
260
+ onLogoutSuccess,
261
+ onLogoutFailed
221
262
  }) {
222
- return /* @__PURE__ */ jsx4(GoogleOAuthProvider, { clientId: googleClientId, children: /* @__PURE__ */ jsx4(UserProvider, { children }) });
223
- }
224
-
225
- // src/components/Buttons/AuthenticationTestButton.tsx
226
- import { Button as Button3 } from "@sparkstudio/common-ui";
227
- import { jsx as jsx5 } from "react/jsx-runtime";
228
- function AuthenticationTestButton({ onSuccess }) {
229
- return /* @__PURE__ */ jsx5(Button3, {});
263
+ return /* @__PURE__ */ jsx4(GoogleOAuthProvider, { clientId: googleClientId, children: /* @__PURE__ */ jsx4(
264
+ UserProvider,
265
+ {
266
+ apiUrl,
267
+ onLoginSuccess,
268
+ onLoginFailed,
269
+ onLogoutSuccess,
270
+ onLogoutFailed,
271
+ children
272
+ }
273
+ ) });
230
274
  }
231
275
 
232
276
  // src/types/Guid.ts
233
277
  var EMPTY_GUID = "00000000-0000-0000-0000-000000000000";
234
278
  export {
235
- AuthenticationTestButton,
236
279
  AuthenticatorProvider,
237
280
  EMPTY_GUID,
238
281
  LoginButton,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sparkstudio/authentication-ui",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",