@asgardeo/react 0.2.3 → 0.3.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.
Files changed (147) hide show
  1. package/README.md +108 -6
  2. package/dist/AsgardeoReactClient.d.ts +37 -0
  3. package/dist/__temp__/api.d.ts +229 -0
  4. package/dist/__temp__/models.d.ts +105 -0
  5. package/dist/api/scim2/getMeProfile.d.ts +39 -0
  6. package/dist/api/scim2/getSchemas.d.ts +39 -0
  7. package/dist/api/scim2/updateMeProfile.d.ts +38 -0
  8. package/dist/cjs/index.js +1888 -45111
  9. package/dist/cjs/index.js.map +7 -1
  10. package/dist/components/actions/SignInButton/BaseSignInButton.d.ts +65 -0
  11. package/dist/components/actions/SignInButton/SignInButton.d.ts +46 -0
  12. package/dist/components/actions/SignOutButton/BaseSignOutButton.d.ts +65 -0
  13. package/dist/components/actions/SignOutButton/SignOutButton.d.ts +44 -0
  14. package/dist/components/actions/SignUpButton/BaseSignUpButton.d.ts +65 -0
  15. package/dist/components/actions/SignUpButton/SignUpButton.d.ts +45 -0
  16. package/dist/components/control/SignedIn.d.ts +45 -0
  17. package/dist/components/control/SignedOut.d.ts +45 -0
  18. package/dist/components/presentation/User.d.ts +57 -0
  19. package/dist/components/presentation/UserDropdown/BaseUserDropdown.d.ts +76 -0
  20. package/dist/components/presentation/UserDropdown/UserDropdown.d.ts +49 -0
  21. package/dist/components/presentation/UserProfile/BaseUserProfile.d.ts +42 -0
  22. package/dist/components/presentation/UserProfile/UserProfile.d.ts +49 -0
  23. package/dist/{cjs/types/components/SignIn/SignIn.d.ts → components/primitives/Avatar/Avatar.d.ts} +25 -14
  24. package/dist/{esm/types/models/use-on.d.ts → components/primitives/Checkbox/Checkbox.d.ts} +20 -9
  25. package/dist/components/primitives/DatePicker/DatePicker.d.ts +50 -0
  26. package/dist/components/primitives/Popover/Popover.d.ts +59 -0
  27. package/dist/components/primitives/Select/Select.d.ts +60 -0
  28. package/dist/components/primitives/TextField/TextField.d.ts +46 -0
  29. package/dist/contexts/AsgardeoContext.d.ts +56 -0
  30. package/dist/{cjs/types/contexts/i18n-context.d.ts → hooks/useAsgardeo.d.ts} +4 -5
  31. package/dist/hooks/useBrowserUrl.d.ts +47 -0
  32. package/dist/index.d.ts +36 -348
  33. package/dist/index.js +1935 -0
  34. package/dist/index.js.map +7 -0
  35. package/dist/{cjs/types/models/public-models.d.ts → models/config.d.ts} +3 -3
  36. package/dist/{cjs/types/hooks/use-config.d.ts → providers/AsgardeoProvider.d.ts} +7 -5
  37. package/dist/{cjs/types/models/asgardeo-provider-props.d.ts → theme/ThemeContext.d.ts} +8 -7
  38. package/dist/{esm/types/models/asgardeo-provider-props.d.ts → theme/ThemeProvider.d.ts} +7 -7
  39. package/dist/{cjs/types/models/use-on.d.ts → theme/types.d.ts} +22 -12
  40. package/dist/{esm/types/oxygen-ui-react-auth-components/index.d.ts → theme/useTheme.d.ts} +3 -3
  41. package/dist/{cjs/types/models/use-config.d.ts → utils/getMappedUserProfileValue.d.ts} +3 -6
  42. package/dist/utils/getUserProfile.d.ts +59 -0
  43. package/package.json +55 -58
  44. package/dist/cjs/types/components/SignIn/fragments/BasicAuth.d.ts +0 -35
  45. package/dist/cjs/types/components/SignIn/fragments/EmailOtp.d.ts +0 -32
  46. package/dist/cjs/types/components/SignIn/fragments/IdentifierFirst.d.ts +0 -35
  47. package/dist/cjs/types/components/SignIn/fragments/LoginOptionsBox.d.ts +0 -30
  48. package/dist/cjs/types/components/SignIn/fragments/SmsOtp.d.ts +0 -21
  49. package/dist/cjs/types/components/SignIn/fragments/Totp.d.ts +0 -33
  50. package/dist/cjs/types/components/SignInButton/SignInButton.d.ts +0 -29
  51. package/dist/cjs/types/components/SignOutButton/SignOutButton.d.ts +0 -27
  52. package/dist/cjs/types/components/SignedIn/SignedIn.d.ts +0 -29
  53. package/dist/cjs/types/components/SignedOut/SignedOut.d.ts +0 -29
  54. package/dist/cjs/types/components/public-components.d.ts +0 -22
  55. package/dist/cjs/types/contexts/asgardeo-context.d.ts +0 -21
  56. package/dist/cjs/types/contexts/branding-preference-context.d.ts +0 -21
  57. package/dist/cjs/types/hooks/use-authentication.d.ts +0 -27
  58. package/dist/cjs/types/hooks/use-on.d.ts +0 -20
  59. package/dist/cjs/types/hooks/use-translations.d.ts +0 -33
  60. package/dist/cjs/types/index.d.ts +0 -22
  61. package/dist/cjs/types/models/auth-context.d.ts +0 -43
  62. package/dist/cjs/types/models/basic-auth-props.d.ts +0 -29
  63. package/dist/cjs/types/models/branding-preference-provider-props.d.ts +0 -22
  64. package/dist/cjs/types/models/email-otp-props.d.ts +0 -26
  65. package/dist/cjs/types/models/i18n.d.ts +0 -34
  66. package/dist/cjs/types/models/jwt-verify-options.d.ts +0 -25
  67. package/dist/cjs/types/models/login-options-box-props.d.ts +0 -24
  68. package/dist/cjs/types/models/sign-in.d.ts +0 -49
  69. package/dist/cjs/types/models/signed-props.d.ts +0 -22
  70. package/dist/cjs/types/models/totp-props.d.ts +0 -26
  71. package/dist/cjs/types/models/use-authentication.d.ts +0 -29
  72. package/dist/cjs/types/models/use-translations.d.ts +0 -22
  73. package/dist/cjs/types/oxygen-ui-react-auth-components/SignIn/SignIn.d.ts +0 -79
  74. package/dist/cjs/types/oxygen-ui-react-auth-components/SignInAlert/SignInAlert.d.ts +0 -37
  75. package/dist/cjs/types/oxygen-ui-react-auth-components/SignInButton/SignInButton.d.ts +0 -27
  76. package/dist/cjs/types/oxygen-ui-react-auth-components/SignInDivider/SignInDivider.d.ts +0 -26
  77. package/dist/cjs/types/oxygen-ui-react-auth-components/SignInFooter/SignInFooter.d.ts +0 -29
  78. package/dist/cjs/types/oxygen-ui-react-auth-components/SignInImage/SignInImage.d.ts +0 -23
  79. package/dist/cjs/types/oxygen-ui-react-auth-components/SignInLink/SignInLink.d.ts +0 -25
  80. package/dist/cjs/types/oxygen-ui-react-auth-components/SignInPaper/SignInPaper.d.ts +0 -26
  81. package/dist/cjs/types/oxygen-ui-react-auth-components/SignInPinInput/SignInPinInput.d.ts +0 -30
  82. package/dist/cjs/types/oxygen-ui-react-auth-components/SignInTextField/SignInTextField.d.ts +0 -26
  83. package/dist/cjs/types/oxygen-ui-react-auth-components/SignInTypography/SignInTypography.d.ts +0 -32
  84. package/dist/cjs/types/oxygen-ui-react-auth-components/index.d.ts +0 -19
  85. package/dist/cjs/types/oxygen-ui-react-auth-components/models/component.d.ts +0 -27
  86. package/dist/cjs/types/providers/AsgardeoProvider.d.ts +0 -34
  87. package/dist/cjs/types/providers/BrandingPreferenceProvider.d.ts +0 -32
  88. package/dist/cjs/types/providers/I18nProvider.d.ts +0 -33
  89. package/dist/cjs/types/theme/generate-theme-sign-in.d.ts +0 -28
  90. package/dist/cjs/types/theme/generate-theme.d.ts +0 -30
  91. package/dist/cjs/types/utils/crypto-utils.d.ts +0 -52
  92. package/dist/cjs/types/utils/session-store.d.ts +0 -25
  93. package/dist/esm/index.js +0 -45151
  94. package/dist/esm/index.js.map +0 -1
  95. package/dist/esm/types/components/SignIn/SignIn.d.ts +0 -31
  96. package/dist/esm/types/components/SignIn/fragments/BasicAuth.d.ts +0 -35
  97. package/dist/esm/types/components/SignIn/fragments/EmailOtp.d.ts +0 -32
  98. package/dist/esm/types/components/SignIn/fragments/IdentifierFirst.d.ts +0 -35
  99. package/dist/esm/types/components/SignIn/fragments/LoginOptionsBox.d.ts +0 -30
  100. package/dist/esm/types/components/SignIn/fragments/SmsOtp.d.ts +0 -21
  101. package/dist/esm/types/components/SignIn/fragments/Totp.d.ts +0 -33
  102. package/dist/esm/types/components/SignInButton/SignInButton.d.ts +0 -29
  103. package/dist/esm/types/components/SignOutButton/SignOutButton.d.ts +0 -27
  104. package/dist/esm/types/components/SignedIn/SignedIn.d.ts +0 -29
  105. package/dist/esm/types/components/SignedOut/SignedOut.d.ts +0 -29
  106. package/dist/esm/types/components/public-components.d.ts +0 -22
  107. package/dist/esm/types/contexts/asgardeo-context.d.ts +0 -21
  108. package/dist/esm/types/contexts/branding-preference-context.d.ts +0 -21
  109. package/dist/esm/types/contexts/i18n-context.d.ts +0 -21
  110. package/dist/esm/types/hooks/use-authentication.d.ts +0 -27
  111. package/dist/esm/types/hooks/use-config.d.ts +0 -23
  112. package/dist/esm/types/hooks/use-on.d.ts +0 -20
  113. package/dist/esm/types/hooks/use-translations.d.ts +0 -33
  114. package/dist/esm/types/index.d.ts +0 -22
  115. package/dist/esm/types/models/auth-context.d.ts +0 -43
  116. package/dist/esm/types/models/basic-auth-props.d.ts +0 -29
  117. package/dist/esm/types/models/branding-preference-provider-props.d.ts +0 -22
  118. package/dist/esm/types/models/email-otp-props.d.ts +0 -26
  119. package/dist/esm/types/models/i18n.d.ts +0 -34
  120. package/dist/esm/types/models/jwt-verify-options.d.ts +0 -25
  121. package/dist/esm/types/models/login-options-box-props.d.ts +0 -24
  122. package/dist/esm/types/models/public-models.d.ts +0 -19
  123. package/dist/esm/types/models/sign-in.d.ts +0 -49
  124. package/dist/esm/types/models/signed-props.d.ts +0 -22
  125. package/dist/esm/types/models/totp-props.d.ts +0 -26
  126. package/dist/esm/types/models/use-authentication.d.ts +0 -29
  127. package/dist/esm/types/models/use-config.d.ts +0 -22
  128. package/dist/esm/types/models/use-translations.d.ts +0 -22
  129. package/dist/esm/types/oxygen-ui-react-auth-components/SignIn/SignIn.d.ts +0 -79
  130. package/dist/esm/types/oxygen-ui-react-auth-components/SignInAlert/SignInAlert.d.ts +0 -37
  131. package/dist/esm/types/oxygen-ui-react-auth-components/SignInButton/SignInButton.d.ts +0 -27
  132. package/dist/esm/types/oxygen-ui-react-auth-components/SignInDivider/SignInDivider.d.ts +0 -26
  133. package/dist/esm/types/oxygen-ui-react-auth-components/SignInFooter/SignInFooter.d.ts +0 -29
  134. package/dist/esm/types/oxygen-ui-react-auth-components/SignInImage/SignInImage.d.ts +0 -23
  135. package/dist/esm/types/oxygen-ui-react-auth-components/SignInLink/SignInLink.d.ts +0 -25
  136. package/dist/esm/types/oxygen-ui-react-auth-components/SignInPaper/SignInPaper.d.ts +0 -26
  137. package/dist/esm/types/oxygen-ui-react-auth-components/SignInPinInput/SignInPinInput.d.ts +0 -30
  138. package/dist/esm/types/oxygen-ui-react-auth-components/SignInTextField/SignInTextField.d.ts +0 -26
  139. package/dist/esm/types/oxygen-ui-react-auth-components/SignInTypography/SignInTypography.d.ts +0 -32
  140. package/dist/esm/types/oxygen-ui-react-auth-components/models/component.d.ts +0 -27
  141. package/dist/esm/types/providers/AsgardeoProvider.d.ts +0 -34
  142. package/dist/esm/types/providers/BrandingPreferenceProvider.d.ts +0 -32
  143. package/dist/esm/types/providers/I18nProvider.d.ts +0 -33
  144. package/dist/esm/types/theme/generate-theme-sign-in.d.ts +0 -28
  145. package/dist/esm/types/theme/generate-theme.d.ts +0 -30
  146. package/dist/esm/types/utils/crypto-utils.d.ts +0 -52
  147. package/dist/esm/types/utils/session-store.d.ts +0 -25
package/dist/index.js ADDED
@@ -0,0 +1,1935 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+
5
+ // src/providers/AsgardeoProvider.tsx
6
+ import { useEffect as useEffect2, useMemo as useMemo2, useRef, useState as useState2 } from "react";
7
+
8
+ // src/AsgardeoReactClient.ts
9
+ import {
10
+ AsgardeoBrowserClient
11
+ } from "@asgardeo/browser";
12
+
13
+ // src/__temp__/api.ts
14
+ import {
15
+ AsgardeoSPAClient,
16
+ Hooks
17
+ } from "@asgardeo/browser";
18
+ var _AuthAPI = class _AuthAPI {
19
+ constructor(spaClient) {
20
+ __publicField(this, "_authState", _AuthAPI.DEFAULT_STATE);
21
+ __publicField(this, "_client");
22
+ __publicField(this, "_isLoading");
23
+ this._client = spaClient ?? AsgardeoSPAClient.getInstance();
24
+ this.getState = this.getState.bind(this);
25
+ this.init = this.init.bind(this);
26
+ this.signIn = this.signIn.bind(this);
27
+ this.signOut = this.signOut.bind(this);
28
+ this.updateState = this.updateState.bind(this);
29
+ }
30
+ _setIsLoading(isLoading) {
31
+ this._isLoading = isLoading;
32
+ }
33
+ _getIsLoading() {
34
+ return this._isLoading;
35
+ }
36
+ isSignedIn() {
37
+ return this.isAuthenticated();
38
+ }
39
+ isLoading() {
40
+ return this._getIsLoading();
41
+ }
42
+ /**
43
+ * Method to return Auth Client instance authentication state.
44
+ *
45
+ * @return {AuthStateInterface} Authentication State.
46
+ */
47
+ getState() {
48
+ return this._authState;
49
+ }
50
+ /**
51
+ * Method to initialize the AuthClient instance.
52
+ *
53
+ * @param {Config} config - `dispatch` function from React Auth Context.
54
+ */
55
+ async init(config) {
56
+ return await this._client.initialize(config);
57
+ }
58
+ /**
59
+ * Method to get the configuration data.
60
+ *
61
+ * @returns {Promise<AuthClientConfig<Config>>} - A promise that resolves with the configuration data.
62
+ */
63
+ async getConfigData() {
64
+ return await this._client.getConfigData();
65
+ }
66
+ /**
67
+ * Method to handle user Sign In requests.
68
+ *
69
+ * @param {any} dispatch - `dispatch` function from React Auth Context.
70
+ * @param {AuthStateInterface} state - Current authentication state in React Auth Context.
71
+ * @param {any} callback - Action to trigger on successful sign in.
72
+ */
73
+ async signIn(config, authorizationCode, sessionState, authState, callback, tokenRequestConfig) {
74
+ return this._client.signIn(config, authorizationCode, sessionState, authState, tokenRequestConfig).then(async (response) => {
75
+ if (!response) {
76
+ return null;
77
+ }
78
+ if (await this._client.isAuthenticated()) {
79
+ const stateToUpdate = {
80
+ allowedScopes: response.allowedScopes,
81
+ displayName: response.displayName,
82
+ email: response.email,
83
+ isAuthenticated: true,
84
+ isLoading: false,
85
+ isSigningOut: false,
86
+ sub: response.sub,
87
+ username: response.username
88
+ };
89
+ this.updateState(stateToUpdate);
90
+ this._setIsLoading(false);
91
+ if (callback) {
92
+ callback(response);
93
+ }
94
+ }
95
+ return response;
96
+ }).catch((error) => {
97
+ return Promise.reject(error);
98
+ });
99
+ }
100
+ /**
101
+ * Method to handle user Sign Out requests.
102
+ *
103
+ * @param {any} dispatch - `dispatch` function from React Auth Context.
104
+ * @param {AuthStateInterface} state - Current authentication state in React Auth Context.
105
+ * @param {any} callback - Action to trigger on successful sign out.
106
+ */
107
+ signOut(callback) {
108
+ return this._client.signOut().then((response) => {
109
+ if (callback) {
110
+ callback(response);
111
+ }
112
+ return response;
113
+ }).catch((error) => {
114
+ return Promise.reject(error);
115
+ });
116
+ }
117
+ /**
118
+ * Method to update Auth Client instance authentication state.
119
+ *
120
+ * @param {AuthStateInterface} state - State values to update in authentication state.
121
+ */
122
+ updateState(state) {
123
+ this._authState = { ...this._authState, ...state };
124
+ }
125
+ /**
126
+ * This method returns a Promise that resolves with the basic user information obtained from the ID token.
127
+ *
128
+ * @return {Promise<BasicUserInfo>} - A promise that resolves with the user information.
129
+ */
130
+ async getBasicUserInfo() {
131
+ return this._client.getBasicUserInfo();
132
+ }
133
+ /**
134
+ * This method sends an API request to a protected endpoint.
135
+ * The access token is automatically attached to the header of the request.
136
+ * This is the only way by which protected endpoints can be accessed
137
+ * when the web worker is used to store session information.
138
+ *
139
+ * @param {HttpRequestConfig} config - The config object containing attributes necessary to send a request.
140
+ *
141
+ * @return {Promise<FetchResponse>} - Returns a Promise that resolves with the response to the request.
142
+ */
143
+ async httpRequest(config) {
144
+ return this._client.httpRequest(config);
145
+ }
146
+ /**
147
+ * This method sends multiple API requests to a protected endpoint.
148
+ * The access token is automatically attached to the header of the request.
149
+ * This is the only way by which multiple requests can be sent to protected endpoints
150
+ * when the web worker is used to store session information.
151
+ *
152
+ * @param {HttpRequestConfig[]} config - The config object containing attributes necessary to send a request.
153
+ *
154
+ * @return {Promise<FetchResponse[]>} - Returns a Promise that resolves with the responses to the requests.
155
+ */
156
+ async httpRequestAll(configs) {
157
+ return this._client.httpRequestAll(configs);
158
+ }
159
+ /**
160
+ * This method allows you to send a request with a custom grant.
161
+ *
162
+ * @param {CustomGrantRequestParams} config - The request parameters.
163
+ *
164
+ * @return {Promise<FetchResponse<any> | SignInResponse>} - A Promise that resolves with
165
+ * the value returned by the custom grant request.
166
+ */
167
+ requestCustomGrant(config, callback, dispatch) {
168
+ return this._client.requestCustomGrant(config).then((response) => {
169
+ if (!response) {
170
+ return null;
171
+ }
172
+ if (config.returnsSession) {
173
+ this.updateState({
174
+ ...this.getState(),
175
+ ...response,
176
+ isAuthenticated: true,
177
+ isLoading: false
178
+ });
179
+ dispatch({ ...response, isAuthenticated: true, isLoading: false });
180
+ }
181
+ callback && callback(response);
182
+ return response;
183
+ }).catch((error) => {
184
+ return Promise.reject(error);
185
+ });
186
+ }
187
+ /**
188
+ * This method ends a user session. The access token is revoked and the session information is destroyed.
189
+ *
190
+ * @return {Promise<boolean>} - A promise that resolves with `true` if the process is successful.
191
+ */
192
+ async revokeAccessToken(dispatch) {
193
+ return this._client.revokeAccessToken().then(() => {
194
+ this.updateState({ ..._AuthAPI.DEFAULT_STATE, isLoading: false });
195
+ dispatch(_AuthAPI.DEFAULT_STATE);
196
+ return true;
197
+ }).catch((error) => {
198
+ return Promise.reject(error);
199
+ });
200
+ }
201
+ /**
202
+ * This method returns a Promise that resolves with an object containing the service endpoints.
203
+ *
204
+ * @return {Promise<ServiceResourcesType} - A Promise that resolves with an object containing the service endpoints.
205
+ */
206
+ async getOIDCServiceEndpoints() {
207
+ return this._client.getOIDCServiceEndpoints();
208
+ }
209
+ /**
210
+ * This methods returns the Axios http client.
211
+ *
212
+ * @return {HttpClientInstance} - The Axios HTTP client.
213
+ */
214
+ async getHttpClient() {
215
+ return this._client.getHttpClient();
216
+ }
217
+ /**
218
+ * This method decodes the payload of the id token and returns it.
219
+ *
220
+ * @return {Promise<DecodedIDTokenPayloadInterface>} - A Promise that resolves with
221
+ * the decoded payload of the id token.
222
+ */
223
+ async getDecodedIDToken() {
224
+ return this._client.getDecodedIDToken();
225
+ }
226
+ /**
227
+ * This method decodes the payload of the idp id token and returns it.
228
+ *
229
+ * @return {Promise<DecodedIDTokenPayloadInterface>} - A Promise that resolves with
230
+ * the decoded payload of the idp id token.
231
+ */
232
+ async getDecodedIDPIDToken() {
233
+ return this._client.getDecodedIDToken();
234
+ }
235
+ /**
236
+ * This method returns the ID token.
237
+ *
238
+ * @return {Promise<string>} - A Promise that resolves with the id token.
239
+ */
240
+ async getIDToken() {
241
+ return this._client.getIDToken();
242
+ }
243
+ /**
244
+ * This method return a Promise that resolves with the access token.
245
+ *
246
+ * **This method will not return the access token if the storage type is set to `webWorker`.**
247
+ *
248
+ * @return {Promise<string>} - A Promise that resolves with the access token.
249
+ */
250
+ async getAccessToken() {
251
+ return this._client.getAccessToken();
252
+ }
253
+ /**
254
+ * This method return a Promise that resolves with the idp access token.
255
+ *
256
+ * **This method will not return the idp access token if the storage type is set to `webWorker`.**
257
+ * **This can be used to access the IDP access token when custom auth grant functionalities are used**
258
+ *
259
+ * @return {Promise<string>} - A Promise that resolves with the idp access token.
260
+ */
261
+ async getIDPAccessToken() {
262
+ return this._client.getIDPAccessToken();
263
+ }
264
+ /**
265
+ * This method refreshes the access token.
266
+ *
267
+ * @return {TokenResponseInterface} - A Promise that resolves with an object containing
268
+ * information about the refreshed access token.
269
+ */
270
+ async refreshAccessToken() {
271
+ return this._client.refreshAccessToken();
272
+ }
273
+ /**
274
+ * This method specifies if the user is authenticated or not.
275
+ *
276
+ * @return {Promise<boolean>} - A Promise that resolves with `true` if teh user is authenticated.
277
+ */
278
+ async isAuthenticated() {
279
+ return this._client.isAuthenticated();
280
+ }
281
+ /**
282
+ * This method specifies if the session is active or not.
283
+ *
284
+ * @return {Promise<boolean>} - A Promise that resolves with `true` if there is an active session.
285
+ */
286
+ async isSessionActive() {
287
+ return this._client.isSessionActive();
288
+ }
289
+ /**
290
+ * This method enables callback functions attached to the http client.
291
+ *
292
+ * @return {Promise<boolean>} - A promise that resolves with True.
293
+ *
294
+ */
295
+ async enableHttpHandler() {
296
+ return this._client.enableHttpHandler();
297
+ }
298
+ /**
299
+ * This method disables callback functions attached to the http client.
300
+ *
301
+ * @return {Promise<boolean>} - A promise that resolves with True.
302
+ */
303
+ async disableHttpHandler() {
304
+ return this._client.disableHttpHandler();
305
+ }
306
+ /**
307
+ * This method updates the configuration that was passed into the constructor when instantiating this class.
308
+ *
309
+ * @param {Partial<AuthClientConfig<T>>} config - A config object to update the SDK configurations with.
310
+ */
311
+ async updateConfig(config) {
312
+ return this._client.updateConfig(config);
313
+ }
314
+ on(hook, callback, id) {
315
+ if (hook === Hooks.CustomGrant) {
316
+ return this._client.on(hook, callback, id);
317
+ }
318
+ return this._client.on(hook, callback);
319
+ }
320
+ /**
321
+ * This method allows you to sign in silently.
322
+ * First, this method sends a prompt none request to see if there is an active user session in the identity server.
323
+ * If there is one, then it requests the access token and stores it. Else, it returns false.
324
+ *
325
+ * @return {Promise<BasicUserInfo | boolean>} - A Promise that resolves with the user information after signing in
326
+ * or with `false` if the user is not signed in.
327
+ *
328
+ * @example
329
+ *```
330
+ * client.trySignInSilently()
331
+ *```
332
+ */
333
+ async trySignInSilently(state, dispatch, additionalParams, tokenRequestConfig) {
334
+ return this._client.trySignInSilently(additionalParams, tokenRequestConfig).then(async (response) => {
335
+ if (!response) {
336
+ this.updateState({ ...this.getState(), isLoading: false });
337
+ dispatch({ ...state, isLoading: false });
338
+ return false;
339
+ }
340
+ if (await this._client.isAuthenticated()) {
341
+ const basicUserInfo = response;
342
+ const stateToUpdate = {
343
+ allowedScopes: basicUserInfo.allowedScopes,
344
+ displayName: basicUserInfo.displayName,
345
+ email: basicUserInfo.email,
346
+ isAuthenticated: true,
347
+ isLoading: false,
348
+ isSigningOut: false,
349
+ sub: basicUserInfo.sub,
350
+ username: basicUserInfo.username
351
+ };
352
+ this.updateState(stateToUpdate);
353
+ dispatch({ ...state, ...stateToUpdate });
354
+ }
355
+ return response;
356
+ }).catch((error) => {
357
+ return Promise.reject(error);
358
+ });
359
+ }
360
+ };
361
+ __publicField(_AuthAPI, "DEFAULT_STATE");
362
+ var AuthAPI = _AuthAPI;
363
+ AuthAPI.DEFAULT_STATE = {
364
+ allowedScopes: "",
365
+ displayName: "",
366
+ email: "",
367
+ isAuthenticated: false,
368
+ isLoading: true,
369
+ sub: "",
370
+ username: ""
371
+ };
372
+ var api_default = AuthAPI;
373
+
374
+ // src/api/scim2/getMeProfile.ts
375
+ import { AsgardeoAPIError, AsgardeoSPAClient as AsgardeoSPAClient2 } from "@asgardeo/browser";
376
+ var httpClient = AsgardeoSPAClient2.getInstance().httpRequest.bind(AsgardeoSPAClient2.getInstance());
377
+ var getMeProfile = async ({ url, ...requestConfig }) => {
378
+ try {
379
+ new URL(url);
380
+ } catch (error) {
381
+ throw new AsgardeoAPIError(
382
+ "Invalid endpoint URL provided",
383
+ "getMeProfile-ValidationError-001",
384
+ "javascript",
385
+ 400,
386
+ "Invalid Request"
387
+ );
388
+ }
389
+ const response = await httpClient({
390
+ url,
391
+ method: "GET",
392
+ headers: {
393
+ "Content-Type": "application/scim+json",
394
+ Accept: "application/json"
395
+ }
396
+ });
397
+ if (!response.data) {
398
+ const errorText = await response.text();
399
+ throw new AsgardeoAPIError(
400
+ `Failed to fetch user profile: ${errorText}`,
401
+ "getMeProfile-ResponseError-001",
402
+ "javascript",
403
+ response.status,
404
+ response.statusText
405
+ );
406
+ }
407
+ return response.data;
408
+ };
409
+ var getMeProfile_default = getMeProfile;
410
+
411
+ // src/utils/getUserProfile.ts
412
+ import { AsgardeoAPIError as AsgardeoAPIError3 } from "@asgardeo/browser";
413
+
414
+ // src/api/scim2/getSchemas.ts
415
+ import { AsgardeoAPIError as AsgardeoAPIError2, AsgardeoSPAClient as AsgardeoSPAClient3 } from "@asgardeo/browser";
416
+ var httpClient2 = AsgardeoSPAClient3.getInstance().httpRequest.bind(AsgardeoSPAClient3.getInstance());
417
+ var getSchemas = async ({ url }) => {
418
+ try {
419
+ new URL(url);
420
+ } catch (error) {
421
+ throw new AsgardeoAPIError2(
422
+ "Invalid endpoint URL provided",
423
+ "getSchemas-ValidationError-001",
424
+ "javascript",
425
+ 400,
426
+ "Invalid Request"
427
+ );
428
+ }
429
+ const response = await httpClient2({
430
+ url,
431
+ method: "GET",
432
+ headers: {
433
+ "Content-Type": "application/json",
434
+ Accept: "application/json"
435
+ }
436
+ });
437
+ if (!response.data) {
438
+ throw new AsgardeoAPIError2(
439
+ `Failed to fetch SCIM2 schemas`,
440
+ "getSchemas-ResponseError-001",
441
+ "javascript",
442
+ response.status,
443
+ response.statusText
444
+ );
445
+ }
446
+ return response.data;
447
+ };
448
+ var getSchemas_default = getSchemas;
449
+
450
+ // src/utils/getUserProfile.ts
451
+ var getUserProfile = async ({ baseUrl }) => {
452
+ try {
453
+ const profile = await getMeProfile_default({ url: `${baseUrl}/scim2/Me` });
454
+ const schemas = await getSchemas_default({ url: `${baseUrl}/scim2/Schemas` });
455
+ const result = [];
456
+ for (const schema of schemas) {
457
+ const schemaId = schema.id;
458
+ const source = schemaId.startsWith("urn:ietf:params:scim:schemas:core:2.0") ? profile : profile[schemaId] ?? {};
459
+ for (const attr of schema.attributes || []) {
460
+ const { name, type, subAttributes, multiValued, caseExact, returned } = attr;
461
+ if (type === "COMPLEX" && subAttributes?.length && typeof source[name] === "object") {
462
+ const complexValue = source[name];
463
+ for (const subAttr of subAttributes) {
464
+ if (complexValue[subAttr.name] !== void 0) {
465
+ const { subAttributes: subAttributes2, ...attrWithoutSubAttrs } = attr;
466
+ const basePath = schemaId === "urn:ietf:params:scim:schemas:core:2.0:User" ? `${name}.${subAttr.name}` : `${schemaId}.${name}.${subAttr.name}`;
467
+ result.push({
468
+ schemaId,
469
+ ...subAttr,
470
+ value: complexValue[subAttr.name],
471
+ parent: {
472
+ ...attrWithoutSubAttrs
473
+ },
474
+ path: basePath
475
+ });
476
+ }
477
+ }
478
+ } else {
479
+ const value = source[name];
480
+ if (value !== void 0) {
481
+ const basePath = schemaId === "urn:ietf:params:scim:schemas:core:2.0:User" ? name : `${schemaId}.${name}`;
482
+ result.push({
483
+ schemaId,
484
+ ...attr,
485
+ value,
486
+ path: basePath
487
+ });
488
+ }
489
+ }
490
+ }
491
+ }
492
+ return result;
493
+ } catch (error) {
494
+ throw new AsgardeoAPIError3(
495
+ "Failed to get user profile",
496
+ "getUserProfile-Error-001",
497
+ "javascript",
498
+ 500,
499
+ "Internal Server Error"
500
+ );
501
+ }
502
+ };
503
+ var getUserProfile_default = getUserProfile;
504
+
505
+ // src/AsgardeoReactClient.ts
506
+ var AsgardeoReactClient = class extends AsgardeoBrowserClient {
507
+ constructor() {
508
+ super();
509
+ __publicField(this, "asgardeo");
510
+ this.asgardeo = new api_default();
511
+ }
512
+ initialize(config) {
513
+ const scopes = Array.isArray(config.scopes) ? config.scopes : config.scopes.split(" ");
514
+ return this.asgardeo.init({
515
+ baseUrl: config.baseUrl,
516
+ clientID: config.clientId,
517
+ signInRedirectURL: config.afterSignInUrl,
518
+ scope: [...scopes, "internal_login"]
519
+ });
520
+ }
521
+ async getUser() {
522
+ const baseUrl = await (await this.asgardeo.getConfigData()).baseUrl;
523
+ const profile = await getUserProfile_default({ baseUrl });
524
+ return profile;
525
+ }
526
+ isLoading() {
527
+ return this.asgardeo.isLoading();
528
+ }
529
+ isSignedIn() {
530
+ return this.asgardeo.isSignedIn();
531
+ }
532
+ signIn(options) {
533
+ return this.asgardeo.signIn(options);
534
+ }
535
+ async signOut(...args) {
536
+ if (args[1] && typeof args[1] !== "function") {
537
+ throw new Error("The second argument must be a function.");
538
+ }
539
+ const response = await this.asgardeo.signOut(args[1]);
540
+ return Promise.resolve(String(response));
541
+ }
542
+ };
543
+ var AsgardeoReactClient_default = AsgardeoReactClient;
544
+
545
+ // src/contexts/AsgardeoContext.ts
546
+ import { createContext } from "react";
547
+ var AsgardeoContext = createContext({
548
+ isLoading: true,
549
+ isSignedIn: false,
550
+ signIn: null,
551
+ signOut: null,
552
+ signUp: null,
553
+ user: null,
554
+ baseUrl: ""
555
+ });
556
+ AsgardeoContext.displayName = "AsgardeoContext";
557
+ var AsgardeoContext_default = AsgardeoContext;
558
+
559
+ // src/hooks/useBrowserUrl.ts
560
+ import { hasAuthParamsInUrl } from "@asgardeo/browser";
561
+ var useBrowserUrl = () => {
562
+ const hasAuthParams = (url, afterSignInUrl) => hasAuthParamsInUrl() && new URL(url.origin + url.pathname).toString() === new URL(afterSignInUrl).toString() || // authParams?.authorizationCode || // FIXME: These are sent externally. Need to see what we can do about this.
563
+ url.searchParams.get("error") !== null;
564
+ return { hasAuthParams };
565
+ };
566
+ var useBrowserUrl_default = useBrowserUrl;
567
+
568
+ // src/theme/ThemeProvider.tsx
569
+ import { useEffect, useMemo, useState } from "react";
570
+ import { createTheme } from "@asgardeo/browser";
571
+
572
+ // src/theme/ThemeContext.ts
573
+ import { createContext as createContext2 } from "react";
574
+ var ThemeContext = createContext2(null);
575
+ ThemeContext.displayName = "ThemeContext";
576
+ var ThemeContext_default = ThemeContext;
577
+
578
+ // src/theme/ThemeProvider.tsx
579
+ import { jsx } from "react/jsx-runtime";
580
+ var applyThemeToDOM = (theme) => {
581
+ Object.entries(theme.cssVariables).forEach(([key, value]) => {
582
+ document.documentElement.style.setProperty(key, value);
583
+ });
584
+ };
585
+ var ThemeProvider = ({
586
+ children,
587
+ theme: themeConfig,
588
+ defaultColorScheme = "light"
589
+ }) => {
590
+ const [colorScheme, setColorScheme] = useState(defaultColorScheme);
591
+ const theme = useMemo(() => createTheme(themeConfig, colorScheme === "dark"), [themeConfig, colorScheme]);
592
+ const toggleTheme = () => {
593
+ setColorScheme((prev) => prev === "light" ? "dark" : "light");
594
+ };
595
+ useEffect(() => {
596
+ applyThemeToDOM(theme);
597
+ }, [theme]);
598
+ const value = {
599
+ theme,
600
+ colorScheme,
601
+ toggleTheme
602
+ };
603
+ return /* @__PURE__ */ jsx(ThemeContext_default.Provider, { value, children });
604
+ };
605
+
606
+ // src/providers/AsgardeoProvider.tsx
607
+ import { jsx as jsx2 } from "react/jsx-runtime";
608
+ var AsgardeoProvider = ({
609
+ afterSignInUrl = window.location.origin,
610
+ baseUrl,
611
+ clientId,
612
+ children,
613
+ scopes,
614
+ preferences
615
+ }) => {
616
+ const reRenderCheckRef = useRef(false);
617
+ const asgardeo = useMemo2(() => new AsgardeoReactClient_default(), []);
618
+ const { hasAuthParams } = useBrowserUrl_default();
619
+ const [user, setUser] = useState2(null);
620
+ const [isSignedInSync, setIsSignedInSync] = useState2(false);
621
+ useEffect2(() => {
622
+ (async () => {
623
+ await asgardeo.initialize({
624
+ afterSignInUrl,
625
+ baseUrl,
626
+ clientId,
627
+ scopes
628
+ });
629
+ })();
630
+ }, []);
631
+ useEffect2(() => {
632
+ if (reRenderCheckRef.current) {
633
+ return;
634
+ }
635
+ reRenderCheckRef.current = true;
636
+ (async () => {
637
+ if (await asgardeo.isSignedIn()) {
638
+ setUser(await asgardeo.getUser());
639
+ return;
640
+ }
641
+ if (hasAuthParams(new URL(window.location.href), afterSignInUrl)) {
642
+ try {
643
+ await signIn(
644
+ { callOnlyOnRedirect: true }
645
+ // authParams?.authorizationCode,
646
+ // authParams?.sessionState,
647
+ // authParams?.state,
648
+ );
649
+ } catch (error) {
650
+ debugger;
651
+ if (error && Object.prototype.hasOwnProperty.call(error, "code")) {
652
+ }
653
+ }
654
+ }
655
+ })();
656
+ }, []);
657
+ useEffect2(() => {
658
+ let interval;
659
+ (async () => {
660
+ try {
661
+ const status = await asgardeo.isSignedIn();
662
+ setIsSignedInSync(status);
663
+ if (!status) {
664
+ interval = setInterval(async () => {
665
+ const newStatus = await asgardeo.isSignedIn();
666
+ if (newStatus) {
667
+ setIsSignedInSync(true);
668
+ clearInterval(interval);
669
+ }
670
+ }, 1e3);
671
+ }
672
+ } catch (error) {
673
+ setIsSignedInSync(false);
674
+ }
675
+ })();
676
+ return () => {
677
+ if (interval) {
678
+ clearInterval(interval);
679
+ }
680
+ };
681
+ }, [asgardeo]);
682
+ const signIn = async (options) => {
683
+ try {
684
+ const response = await asgardeo.signIn(options);
685
+ setUser(await asgardeo.getUser());
686
+ return response;
687
+ } catch (error) {
688
+ throw new Error(`Error while signing in: ${error}`);
689
+ }
690
+ };
691
+ const signUp = () => {
692
+ throw new Error("Not implemented");
693
+ };
694
+ const signOut = async (options, afterSignOut) => asgardeo.signOut(options, afterSignOut);
695
+ const isDarkMode = useMemo2(() => {
696
+ if (!preferences?.theme?.mode || preferences.theme.mode === "system") {
697
+ return window.matchMedia("(prefers-color-scheme: dark)").matches;
698
+ }
699
+ return preferences.theme.mode === "dark";
700
+ }, [preferences?.theme?.mode]);
701
+ return /* @__PURE__ */ jsx2(
702
+ AsgardeoContext_default.Provider,
703
+ {
704
+ value: {
705
+ isLoading: false,
706
+ isSignedIn: isSignedInSync,
707
+ signIn,
708
+ signOut,
709
+ signUp: () => {
710
+ throw new Error("Sign up functionality not implemented yet");
711
+ },
712
+ user,
713
+ baseUrl
714
+ },
715
+ children: /* @__PURE__ */ jsx2(ThemeProvider, { theme: preferences?.theme?.overrides, defaultColorScheme: isDarkMode ? "dark" : "light", children })
716
+ }
717
+ );
718
+ };
719
+ var AsgardeoProvider_default = AsgardeoProvider;
720
+
721
+ // src/hooks/useAsgardeo.ts
722
+ import { useContext } from "react";
723
+ var useAsgardeo = () => {
724
+ const context = useContext(AsgardeoContext_default);
725
+ if (!context) {
726
+ throw new Error("useAsgardeo must be used within an AsgardeoProvider");
727
+ }
728
+ return context;
729
+ };
730
+ var useAsgardeo_default = useAsgardeo;
731
+
732
+ // src/components/actions/SignInButton/BaseSignInButton.tsx
733
+ import {
734
+ forwardRef
735
+ } from "react";
736
+ import { withVendorCSSClassPrefix } from "@asgardeo/browser";
737
+ import clsx from "clsx";
738
+ import { Fragment, jsx as jsx3 } from "react/jsx-runtime";
739
+ var BaseSignInButton = forwardRef(
740
+ ({ children, className, style, signIn, isLoading, ...rest }, ref) => {
741
+ if (typeof children === "function") {
742
+ return /* @__PURE__ */ jsx3(Fragment, { children: children({ signIn, isLoading }) });
743
+ }
744
+ return /* @__PURE__ */ jsx3(
745
+ "button",
746
+ {
747
+ ref,
748
+ className: clsx(withVendorCSSClassPrefix("sign-in-button"), className),
749
+ style,
750
+ disabled: isLoading,
751
+ type: "button",
752
+ ...rest,
753
+ children
754
+ }
755
+ );
756
+ }
757
+ );
758
+ BaseSignInButton.displayName = "BaseSignInButton";
759
+ var BaseSignInButton_default = BaseSignInButton;
760
+
761
+ // src/components/actions/SignInButton/SignInButton.tsx
762
+ import { forwardRef as forwardRef2, useState as useState3 } from "react";
763
+ import { jsx as jsx4 } from "react/jsx-runtime";
764
+ var SignInButton = forwardRef2(({ children = "Sign In", onClick, ...rest }, ref) => {
765
+ const { signIn } = useAsgardeo_default();
766
+ const [isLoading, setIsLoading] = useState3(false);
767
+ const handleSignIn = async (e) => {
768
+ try {
769
+ setIsLoading(true);
770
+ await signIn();
771
+ if (onClick) {
772
+ onClick(e);
773
+ }
774
+ } catch (error) {
775
+ throw new Error(`Sign in failed: ${error instanceof Error ? error.message : String(error)}`);
776
+ } finally {
777
+ setIsLoading(false);
778
+ }
779
+ };
780
+ return /* @__PURE__ */ jsx4(BaseSignInButton_default, { ref, onClick: handleSignIn, isLoading, signIn: handleSignIn, ...rest, children });
781
+ });
782
+ SignInButton.displayName = "SignInButton";
783
+ var SignInButton_default = SignInButton;
784
+
785
+ // src/components/actions/SignOutButton/BaseSignOutButton.tsx
786
+ import {
787
+ forwardRef as forwardRef3
788
+ } from "react";
789
+ import { withVendorCSSClassPrefix as withVendorCSSClassPrefix2 } from "@asgardeo/browser";
790
+ import clsx2 from "clsx";
791
+ import { Fragment as Fragment2, jsx as jsx5 } from "react/jsx-runtime";
792
+ var BaseSignOutButton = forwardRef3(
793
+ ({ children, className, style, signOut, isLoading, ...rest }, ref) => {
794
+ if (typeof children === "function") {
795
+ return /* @__PURE__ */ jsx5(Fragment2, { children: children({ signOut, isLoading }) });
796
+ }
797
+ return /* @__PURE__ */ jsx5(
798
+ "button",
799
+ {
800
+ ref,
801
+ className: clsx2(withVendorCSSClassPrefix2("sign-out-button"), className),
802
+ style,
803
+ disabled: isLoading,
804
+ type: "button",
805
+ ...rest,
806
+ children
807
+ }
808
+ );
809
+ }
810
+ );
811
+ BaseSignOutButton.displayName = "BaseSignOutButton";
812
+ var BaseSignOutButton_default = BaseSignOutButton;
813
+
814
+ // src/components/actions/SignOutButton/SignOutButton.tsx
815
+ import { forwardRef as forwardRef4, useState as useState4 } from "react";
816
+ import { jsx as jsx6 } from "react/jsx-runtime";
817
+ var SignOutButton = forwardRef4(({ children = "Sign Out", onClick, ...rest }, ref) => {
818
+ const { signOut } = useAsgardeo_default();
819
+ const [isLoading, setIsLoading] = useState4(false);
820
+ const handleSignOut = async (e) => {
821
+ try {
822
+ setIsLoading(true);
823
+ await signOut();
824
+ if (onClick) {
825
+ onClick(e);
826
+ }
827
+ } catch (error) {
828
+ throw new Error(`Sign out failed: ${error instanceof Error ? error.message : String(error)}`);
829
+ } finally {
830
+ setIsLoading(false);
831
+ }
832
+ };
833
+ return /* @__PURE__ */ jsx6(BaseSignOutButton_default, { ref, onClick: handleSignOut, isLoading, signOut: handleSignOut, ...rest, children });
834
+ });
835
+ SignOutButton.displayName = "SignOutButton";
836
+ var SignOutButton_default = SignOutButton;
837
+
838
+ // src/components/actions/SignUpButton/BaseSignUpButton.tsx
839
+ import {
840
+ forwardRef as forwardRef5
841
+ } from "react";
842
+ import { withVendorCSSClassPrefix as withVendorCSSClassPrefix3 } from "@asgardeo/browser";
843
+ import clsx3 from "clsx";
844
+ import { Fragment as Fragment3, jsx as jsx7 } from "react/jsx-runtime";
845
+ var BaseSignUpButton = forwardRef5(
846
+ ({ children, className, style, signUp, isLoading, ...rest }, ref) => {
847
+ if (typeof children === "function") {
848
+ return /* @__PURE__ */ jsx7(Fragment3, { children: children({ signUp, isLoading }) });
849
+ }
850
+ return /* @__PURE__ */ jsx7(
851
+ "button",
852
+ {
853
+ ref,
854
+ className: clsx3(withVendorCSSClassPrefix3("sign-up-button"), className),
855
+ style,
856
+ disabled: isLoading,
857
+ type: "button",
858
+ ...rest,
859
+ children
860
+ }
861
+ );
862
+ }
863
+ );
864
+ BaseSignUpButton.displayName = "BaseSignUpButton";
865
+ var BaseSignUpButton_default = BaseSignUpButton;
866
+
867
+ // src/components/actions/SignUpButton/SignUpButton.tsx
868
+ import { forwardRef as forwardRef6, useState as useState5 } from "react";
869
+ import { jsx as jsx8 } from "react/jsx-runtime";
870
+ var SignUpButton = forwardRef6(({ children = "Sign Up", onClick, ...rest }, ref) => {
871
+ const { signUp } = useAsgardeo_default();
872
+ const [isLoading, setIsLoading] = useState5(false);
873
+ const handleSignUp = async (e) => {
874
+ try {
875
+ setIsLoading(true);
876
+ await signUp();
877
+ if (onClick) {
878
+ onClick(e);
879
+ }
880
+ } catch (error) {
881
+ throw new Error(`Sign up failed: ${error instanceof Error ? error.message : String(error)}`);
882
+ } finally {
883
+ setIsLoading(false);
884
+ }
885
+ };
886
+ return /* @__PURE__ */ jsx8(BaseSignUpButton_default, { ref, onClick: handleSignUp, isLoading, signUp: handleSignUp, ...rest, children });
887
+ });
888
+ SignUpButton.displayName = "SignUpButton";
889
+ var SignUpButton_default = SignUpButton;
890
+
891
+ // src/components/control/SignedIn.tsx
892
+ import { Fragment as Fragment4, jsx as jsx9 } from "react/jsx-runtime";
893
+ var SignedIn = ({
894
+ children,
895
+ fallback = null
896
+ }) => {
897
+ const { isSignedIn } = useAsgardeo_default();
898
+ if (!isSignedIn) {
899
+ return /* @__PURE__ */ jsx9(Fragment4, { children: fallback });
900
+ }
901
+ return /* @__PURE__ */ jsx9(Fragment4, { children });
902
+ };
903
+ SignedIn.displayName = "SignedIn";
904
+ var SignedIn_default = SignedIn;
905
+
906
+ // src/components/control/SignedOut.tsx
907
+ import { Fragment as Fragment5, jsx as jsx10 } from "react/jsx-runtime";
908
+ var SignedOut = ({
909
+ children,
910
+ fallback = null
911
+ }) => {
912
+ const { isSignedIn } = useAsgardeo_default();
913
+ if (!isSignedIn) {
914
+ return /* @__PURE__ */ jsx10(Fragment5, { children });
915
+ }
916
+ return /* @__PURE__ */ jsx10(Fragment5, { children: fallback });
917
+ };
918
+ SignedOut.displayName = "SignedOut";
919
+ var SignedOut_default = SignedOut;
920
+
921
+ // src/components/presentation/User.tsx
922
+ import { Fragment as Fragment6, jsx as jsx11 } from "react/jsx-runtime";
923
+ var User4 = ({ children, fallback = null }) => {
924
+ const { user } = useAsgardeo_default();
925
+ if (!user) {
926
+ return /* @__PURE__ */ jsx11(Fragment6, { children: fallback });
927
+ }
928
+ return /* @__PURE__ */ jsx11(Fragment6, { children: children(user) });
929
+ };
930
+ User4.displayName = "User";
931
+ var User_default = User4;
932
+
933
+ // src/components/presentation/UserProfile/BaseUserProfile.tsx
934
+ import { useMemo as useMemo5, useState as useState7, useCallback } from "react";
935
+
936
+ // src/components/primitives/Popover/Popover.tsx
937
+ import React, { useEffect as useEffect3, useMemo as useMemo3, useState as useState6 } from "react";
938
+ import { createPortal } from "react-dom";
939
+
940
+ // src/theme/useTheme.ts
941
+ import { useContext as useContext2 } from "react";
942
+ var useTheme = () => {
943
+ const context = useContext2(ThemeContext_default);
944
+ if (!context) {
945
+ throw new Error("useTheme must be used within a ThemeProvider");
946
+ }
947
+ return context;
948
+ };
949
+
950
+ // src/components/primitives/Popover/Popover.tsx
951
+ import { withVendorCSSClassPrefix as withVendorCSSClassPrefix4 } from "@asgardeo/browser";
952
+ import clsx4 from "clsx";
953
+ import { jsx as jsx12, jsxs } from "react/jsx-runtime";
954
+ var useStyles = () => {
955
+ const { theme, colorScheme } = useTheme();
956
+ return useMemo3(
957
+ () => ({
958
+ overlay: {
959
+ position: "fixed",
960
+ top: 0,
961
+ left: 0,
962
+ right: 0,
963
+ bottom: 0,
964
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
965
+ zIndex: 999
966
+ },
967
+ content: {
968
+ position: "fixed",
969
+ top: "50%",
970
+ left: "50%",
971
+ transform: "translate(-50%, -50%)",
972
+ zIndex: 1e3,
973
+ maxHeight: "90vh",
974
+ overflowY: "auto",
975
+ background: theme.colors.surface,
976
+ borderRadius: theme.borderRadius.large,
977
+ boxShadow: `0 2px 8px ${colorScheme === "dark" ? "rgba(0, 0, 0, 0.3)" : "rgba(0, 0, 0, 0.15)"}`
978
+ },
979
+ contentBody: {},
980
+ header: {
981
+ display: "flex",
982
+ justifyContent: "space-between",
983
+ alignItems: "center",
984
+ padding: `${theme.spacing.unit * 3}px ${theme.spacing.unit * 4.5}px`,
985
+ borderBottom: `1px solid ${theme.colors.border}`
986
+ },
987
+ headerTitle: {
988
+ margin: 0,
989
+ fontSize: "1.2rem",
990
+ fontWeight: 600,
991
+ color: theme.colors.text.primary
992
+ },
993
+ closeButton: {
994
+ background: "none",
995
+ border: "none",
996
+ cursor: "pointer",
997
+ padding: theme.spacing.unit / 2 + "px",
998
+ color: theme.colors.text.secondary,
999
+ fontSize: "1.2rem",
1000
+ "&:hover": {
1001
+ color: theme.colors.text.primary
1002
+ }
1003
+ }
1004
+ }),
1005
+ [theme, colorScheme]
1006
+ );
1007
+ };
1008
+ var PopoverContext = React.createContext({});
1009
+ var PopoverHeader = ({ children }) => {
1010
+ const styles = useStyles();
1011
+ const { onClose } = React.useContext(PopoverContext);
1012
+ return /* @__PURE__ */ jsxs("div", { style: styles.header, children: [
1013
+ children && /* @__PURE__ */ jsx12("h3", { style: styles.headerTitle, children }),
1014
+ onClose && /* @__PURE__ */ jsx12("button", { style: styles.closeButton, onClick: onClose, "aria-label": "Close", children: "\xD7" })
1015
+ ] });
1016
+ };
1017
+ var PopoverContent = ({ children }) => {
1018
+ const styles = useStyles();
1019
+ return /* @__PURE__ */ jsx12("div", { style: styles.contentBody, children });
1020
+ };
1021
+ var Popover = ({ isOpen, children, onClose, className = "", portalId = "wso2-popover-root", mode = "modal" }) => {
1022
+ const [portalEl, setPortalEl] = useState6(null);
1023
+ const styles = useStyles();
1024
+ useEffect3(() => {
1025
+ const existing = document.getElementById(portalId);
1026
+ if (existing) {
1027
+ setPortalEl(existing);
1028
+ return void 0;
1029
+ }
1030
+ const el = document.createElement("div");
1031
+ el.id = portalId;
1032
+ document.body.appendChild(el);
1033
+ setPortalEl(el);
1034
+ return () => {
1035
+ if (document.getElementById(portalId)) {
1036
+ document.getElementById(portalId)?.remove();
1037
+ }
1038
+ };
1039
+ }, [portalId]);
1040
+ useEffect3(() => {
1041
+ const handleEscape = (event) => {
1042
+ if (event.key === "Escape" && isOpen) {
1043
+ onClose();
1044
+ }
1045
+ };
1046
+ document.addEventListener("keydown", handleEscape);
1047
+ return () => document.removeEventListener("keydown", handleEscape);
1048
+ }, [isOpen, onClose]);
1049
+ if (!isOpen || !portalEl) {
1050
+ return null;
1051
+ }
1052
+ return createPortal(
1053
+ /* @__PURE__ */ jsx12(PopoverContext.Provider, { value: { onClose }, children: /* @__PURE__ */ jsxs("div", { className: clsx4(withVendorCSSClassPrefix4("popover"), className), children: [
1054
+ mode === "modal" && /* @__PURE__ */ jsx12("div", { className: withVendorCSSClassPrefix4("popover-overlay"), style: styles["overlay"], onClick: onClose }),
1055
+ /* @__PURE__ */ jsx12("div", { className: withVendorCSSClassPrefix4("popover-content"), style: styles["content"], children })
1056
+ ] }) }),
1057
+ portalEl
1058
+ );
1059
+ };
1060
+ Popover.Header = PopoverHeader;
1061
+ Popover.Content = PopoverContent;
1062
+
1063
+ // src/components/primitives/Avatar/Avatar.tsx
1064
+ import { useMemo as useMemo4 } from "react";
1065
+ import { withVendorCSSClassPrefix as withVendorCSSClassPrefix5 } from "@asgardeo/browser";
1066
+ import clsx5 from "clsx";
1067
+ import { jsx as jsx13 } from "react/jsx-runtime";
1068
+ var useStyles2 = ({ size }) => {
1069
+ const { theme, colorScheme } = useTheme();
1070
+ return useMemo4(
1071
+ () => ({
1072
+ avatar: {
1073
+ width: `${size}px`,
1074
+ height: `${size}px`,
1075
+ borderRadius: "50%",
1076
+ overflow: "hidden",
1077
+ backgroundColor: theme.colors.surface,
1078
+ display: "flex",
1079
+ alignItems: "center",
1080
+ justifyContent: "center",
1081
+ fontSize: `${size * 0.4}px`,
1082
+ fontWeight: 500,
1083
+ color: theme.colors.text.primary,
1084
+ border: `1px solid ${theme.colors.border}`,
1085
+ boxShadow: colorScheme === "dark" ? "none" : "0 2px 4px rgba(0, 0, 0, 0.1)"
1086
+ },
1087
+ image: {
1088
+ width: "100%",
1089
+ height: "100%",
1090
+ objectFit: "cover"
1091
+ }
1092
+ }),
1093
+ [size, theme, colorScheme]
1094
+ );
1095
+ };
1096
+ var Avatar = ({ imageUrl, alt = "User avatar", size = 64, name, className = "" }) => {
1097
+ const styles = useStyles2({ size });
1098
+ const getInitials = (name2) => {
1099
+ return name2.split(" ").map((part) => part[0]).slice(0, 2).join("").toUpperCase();
1100
+ };
1101
+ return /* @__PURE__ */ jsx13("div", { style: styles.avatar, className: clsx5(withVendorCSSClassPrefix5("avatar"), className), children: imageUrl ? /* @__PURE__ */ jsx13("img", { src: imageUrl, alt, style: styles.image }) : name ? getInitials(name) : "?" });
1102
+ };
1103
+
1104
+ // src/components/primitives/TextField/TextField.tsx
1105
+ import clsx6 from "clsx";
1106
+ import { jsx as jsx14, jsxs as jsxs2 } from "react/jsx-runtime";
1107
+ var TextField = ({ label, error, required, className, disabled, helperText, style = {}, ...rest }) => {
1108
+ const { theme } = useTheme();
1109
+ const containerStyle = {
1110
+ marginBottom: theme.spacing.unit * 2 + "px",
1111
+ ...style
1112
+ };
1113
+ const labelStyle = {
1114
+ display: "block",
1115
+ marginBottom: theme.spacing.unit + "px",
1116
+ color: error ? theme.colors.error.main : theme.colors.text.secondary,
1117
+ fontSize: "0.875rem",
1118
+ fontWeight: 500
1119
+ };
1120
+ const inputStyle = {
1121
+ width: "100%",
1122
+ padding: `${theme.spacing.unit}px ${theme.spacing.unit * 1.5}px`,
1123
+ border: `1px solid ${error ? theme.colors.error.main : theme.colors.border}`,
1124
+ borderRadius: theme.borderRadius.small,
1125
+ fontSize: "1rem",
1126
+ color: theme.colors.text.primary,
1127
+ backgroundColor: disabled ? theme.colors.background.disabled : theme.colors.background.surface,
1128
+ outline: "none",
1129
+ transition: "border-color 0.2s ease"
1130
+ };
1131
+ const helperTextStyle = {
1132
+ fontSize: "0.75rem",
1133
+ color: error ? theme.colors.error.main : theme.colors.text.secondary,
1134
+ marginTop: theme.spacing.unit / 2 + "px"
1135
+ };
1136
+ return /* @__PURE__ */ jsxs2("div", { style: containerStyle, className: clsx6("asgardeo-text-field", className), children: [
1137
+ label && /* @__PURE__ */ jsxs2("label", { style: labelStyle, children: [
1138
+ label,
1139
+ required && /* @__PURE__ */ jsx14("span", { style: { color: theme.colors.error.main }, children: " *" })
1140
+ ] }),
1141
+ /* @__PURE__ */ jsx14("input", { style: inputStyle, disabled, "aria-invalid": !!error, "aria-required": required, ...rest }),
1142
+ (error || helperText) && /* @__PURE__ */ jsx14("div", { style: helperTextStyle, children: error || helperText })
1143
+ ] });
1144
+ };
1145
+
1146
+ // src/components/primitives/DatePicker/DatePicker.tsx
1147
+ import clsx7 from "clsx";
1148
+ import { jsx as jsx15, jsxs as jsxs3 } from "react/jsx-runtime";
1149
+ var DatePicker = ({
1150
+ label,
1151
+ error,
1152
+ className,
1153
+ required,
1154
+ disabled,
1155
+ helperText,
1156
+ dateFormat = "yyyy-MM-dd",
1157
+ style = {},
1158
+ ...rest
1159
+ }) => {
1160
+ const { theme } = useTheme();
1161
+ const containerStyle = {
1162
+ marginBottom: theme.spacing.unit * 2 + "px",
1163
+ ...style
1164
+ };
1165
+ const labelStyle = {
1166
+ display: "block",
1167
+ marginBottom: theme.spacing.unit + "px",
1168
+ color: error ? theme.colors.error.main : theme.colors.text.secondary,
1169
+ fontSize: "0.875rem",
1170
+ fontWeight: 500
1171
+ };
1172
+ const inputStyle = {
1173
+ width: "100%",
1174
+ padding: `${theme.spacing.unit}px ${theme.spacing.unit * 1.5}px`,
1175
+ border: `1px solid ${error ? theme.colors.error.main : theme.colors.border}`,
1176
+ borderRadius: theme.borderRadius.small,
1177
+ fontSize: "1rem",
1178
+ color: theme.colors.text.primary,
1179
+ backgroundColor: disabled ? theme.colors.background.disabled : theme.colors.background.surface,
1180
+ outline: "none",
1181
+ transition: "border-color 0.2s ease"
1182
+ };
1183
+ const helperTextStyle = {
1184
+ fontSize: "0.75rem",
1185
+ color: error ? theme.colors.error.main : theme.colors.text.secondary,
1186
+ marginTop: theme.spacing.unit / 2 + "px"
1187
+ };
1188
+ return /* @__PURE__ */ jsxs3("div", { style: containerStyle, className: clsx7("asgardeo-date-picker", className), children: [
1189
+ label && /* @__PURE__ */ jsxs3("label", { style: labelStyle, children: [
1190
+ label,
1191
+ required && /* @__PURE__ */ jsx15("span", { style: { color: theme.colors.error.main }, children: " *" })
1192
+ ] }),
1193
+ /* @__PURE__ */ jsx15(
1194
+ "input",
1195
+ {
1196
+ type: "date",
1197
+ pattern: "\\d{4}-\\d{2}-\\d{2}",
1198
+ placeholder: dateFormat,
1199
+ style: inputStyle,
1200
+ disabled,
1201
+ "aria-invalid": !!error,
1202
+ "aria-required": required,
1203
+ ...rest
1204
+ }
1205
+ ),
1206
+ (error || helperText) && /* @__PURE__ */ jsx15("div", { style: helperTextStyle, children: error || helperText })
1207
+ ] });
1208
+ };
1209
+
1210
+ // src/components/primitives/Checkbox/Checkbox.tsx
1211
+ import clsx8 from "clsx";
1212
+ import { jsx as jsx16, jsxs as jsxs4 } from "react/jsx-runtime";
1213
+ var Checkbox = ({ label, error, className, required, helperText, style = {}, ...rest }) => {
1214
+ const { theme } = useTheme();
1215
+ const containerStyle = {
1216
+ marginBottom: theme.spacing.unit * 2 + "px",
1217
+ display: "flex",
1218
+ alignItems: "center",
1219
+ ...style
1220
+ };
1221
+ const inputStyle = {
1222
+ width: theme.spacing.unit * 2.5 + "px",
1223
+ height: theme.spacing.unit * 2.5 + "px",
1224
+ marginRight: theme.spacing.unit + "px",
1225
+ accentColor: theme.colors.primary.main
1226
+ };
1227
+ const labelStyle = {
1228
+ color: error ? theme.colors.error.main : theme.colors.text.primary,
1229
+ fontSize: "0.875rem"
1230
+ };
1231
+ const helperTextStyle = {
1232
+ fontSize: "0.75rem",
1233
+ color: error ? theme.colors.error.main : theme.colors.text.secondary,
1234
+ marginTop: theme.spacing.unit / 2 + "px",
1235
+ marginLeft: theme.spacing.unit * 3.5 + "px"
1236
+ };
1237
+ return /* @__PURE__ */ jsxs4("div", { className: clsx8("asgardeo-checkbox", className), children: [
1238
+ /* @__PURE__ */ jsxs4("div", { style: containerStyle, children: [
1239
+ /* @__PURE__ */ jsx16("input", { type: "checkbox", style: inputStyle, "aria-invalid": !!error, "aria-required": required, ...rest }),
1240
+ label && /* @__PURE__ */ jsxs4("label", { style: labelStyle, children: [
1241
+ label,
1242
+ required && /* @__PURE__ */ jsx16("span", { style: { color: theme.colors.error.main }, children: " *" })
1243
+ ] })
1244
+ ] }),
1245
+ (error || helperText) && /* @__PURE__ */ jsx16("div", { style: helperTextStyle, children: error || helperText })
1246
+ ] });
1247
+ };
1248
+
1249
+ // src/components/presentation/UserProfile/BaseUserProfile.tsx
1250
+ import { withVendorCSSClassPrefix as withVendorCSSClassPrefix6 } from "@asgardeo/browser";
1251
+ import clsx9 from "clsx";
1252
+
1253
+ // src/utils/getMappedUserProfileValue.ts
1254
+ var getMappedUserProfileValue = (key, mappings, user) => {
1255
+ const mappedKey = mappings[key];
1256
+ if (Array.isArray(user)) {
1257
+ if (Array.isArray(mappedKey)) {
1258
+ for (const field of mappedKey) {
1259
+ const found2 = user.find((u) => u.name === field);
1260
+ if (found2?.value !== void 0) {
1261
+ return found2.value;
1262
+ }
1263
+ }
1264
+ } else {
1265
+ const found2 = user.find((u) => u.name === mappedKey);
1266
+ if (found2?.value !== void 0) {
1267
+ return found2.value;
1268
+ }
1269
+ }
1270
+ const found = user.find((u) => u.name === key);
1271
+ return found?.value;
1272
+ }
1273
+ return mappedKey ? user[mappedKey] : user[key];
1274
+ };
1275
+ var getMappedUserProfileValue_default = getMappedUserProfileValue;
1276
+
1277
+ // src/components/presentation/UserProfile/BaseUserProfile.tsx
1278
+ import { Fragment as Fragment7, jsx as jsx17, jsxs as jsxs5 } from "react/jsx-runtime";
1279
+ var BaseUserProfile = ({
1280
+ fallback = /* @__PURE__ */ jsx17("div", { children: "Please sign in to view your profile" }),
1281
+ className = "",
1282
+ cardLayout = true,
1283
+ user,
1284
+ mode = "inline",
1285
+ portalId = "asgardeo-user-profile",
1286
+ title = "User Profile",
1287
+ attributeMapping = {},
1288
+ editable = true,
1289
+ onChange,
1290
+ onSubmit,
1291
+ onUpdate,
1292
+ saveButtonText = "Save Changes",
1293
+ cancelButtonText = "Cancel"
1294
+ }) => {
1295
+ const { theme } = useTheme();
1296
+ const [isOpen, setIsOpen] = useState7(mode === "popup");
1297
+ const [editedUser, setEditedUser] = useState7(user);
1298
+ const [editingFields, setEditingFields] = useState7({});
1299
+ const PencilIcon = () => /* @__PURE__ */ jsx17(
1300
+ "svg",
1301
+ {
1302
+ width: "16",
1303
+ height: "16",
1304
+ viewBox: "0 0 24 24",
1305
+ fill: "none",
1306
+ stroke: "currentColor",
1307
+ strokeWidth: "2",
1308
+ strokeLinecap: "round",
1309
+ strokeLinejoin: "round",
1310
+ children: /* @__PURE__ */ jsx17("path", { d: "M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z" })
1311
+ }
1312
+ );
1313
+ const toggleFieldEdit = useCallback((fieldName) => {
1314
+ setEditingFields((prev) => ({
1315
+ ...prev,
1316
+ [fieldName]: !prev[fieldName]
1317
+ }));
1318
+ }, []);
1319
+ function set(obj, path, value) {
1320
+ const keys = path.split(".");
1321
+ let current = obj;
1322
+ for (let i = 0; i < keys.length; i++) {
1323
+ const key = keys[i];
1324
+ if (i === keys.length - 1) {
1325
+ current[key] = value;
1326
+ } else {
1327
+ if (!current[key] || typeof current[key] !== "object") {
1328
+ current[key] = {};
1329
+ }
1330
+ current = current[key];
1331
+ }
1332
+ }
1333
+ }
1334
+ const handleFieldSave = useCallback(
1335
+ (schema) => {
1336
+ let payload = {};
1337
+ const fieldName = schema.name;
1338
+ const fieldValue = editedUser && fieldName && editedUser[fieldName] !== void 0 ? editedUser[fieldName] : schema.value;
1339
+ set(payload, schema.path, fieldValue);
1340
+ onUpdate(payload);
1341
+ toggleFieldEdit(fieldName);
1342
+ },
1343
+ [editedUser, onUpdate, toggleFieldEdit]
1344
+ );
1345
+ const handleFieldCancel = useCallback(
1346
+ (fieldName) => {
1347
+ setEditedUser((prev) => ({
1348
+ ...prev,
1349
+ [fieldName]: user[fieldName]
1350
+ }));
1351
+ toggleFieldEdit(fieldName);
1352
+ },
1353
+ [user, toggleFieldEdit]
1354
+ );
1355
+ const formatLabel = useCallback((key) => {
1356
+ return key.split(/(?=[A-Z])|_/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
1357
+ }, []);
1358
+ const styles = useStyles3();
1359
+ const buttonStyle = useMemo5(
1360
+ () => ({
1361
+ padding: `${theme.spacing.unit}px ${theme.spacing.unit * 2}px`,
1362
+ margin: `${theme.spacing.unit}px`,
1363
+ borderRadius: theme.borderRadius.small,
1364
+ border: "none",
1365
+ cursor: "pointer",
1366
+ fontSize: "0.875rem",
1367
+ fontWeight: 500
1368
+ }),
1369
+ [theme]
1370
+ );
1371
+ const saveButtonStyle = useMemo5(
1372
+ () => ({
1373
+ ...buttonStyle,
1374
+ backgroundColor: theme.colors.primary.main,
1375
+ color: theme.colors.primary.contrastText
1376
+ }),
1377
+ [theme, buttonStyle]
1378
+ );
1379
+ const cancelButtonStyle = useMemo5(
1380
+ () => ({
1381
+ ...buttonStyle,
1382
+ backgroundColor: theme.colors.secondary.main,
1383
+ border: `1px solid ${theme.colors.border}`
1384
+ }),
1385
+ [theme, buttonStyle]
1386
+ );
1387
+ const defaultAttributeMappings = {
1388
+ picture: ["profile", "profileUrl"],
1389
+ firstName: "givenName",
1390
+ lastName: "familyName"
1391
+ };
1392
+ const mergedMappings = { ...defaultAttributeMappings, ...attributeMapping };
1393
+ const renderSchemaField = (schema, isEditing, onEditValue) => {
1394
+ if (!schema) return null;
1395
+ const { value, displayName, description, name, type, required, mutability, subAttributes } = schema;
1396
+ const label = displayName || description || name || "";
1397
+ if (subAttributes && Array.isArray(subAttributes)) {
1398
+ return /* @__PURE__ */ jsx17(Fragment7, { children: subAttributes.map((subAttr, index) => /* @__PURE__ */ jsxs5("div", { style: styles.field, children: [
1399
+ /* @__PURE__ */ jsx17("span", { style: styles.label, children: subAttr.displayName || subAttr.description || "" }),
1400
+ /* @__PURE__ */ jsx17("div", { style: styles.value, children: Array.isArray(subAttr.value) ? subAttr.value.map((item) => typeof item === "object" ? JSON.stringify(item) : String(item)).join(", ") : typeof subAttr.value === "object" ? JSON.stringify(subAttr.value) : String(subAttr.value) })
1401
+ ] }, index)) });
1402
+ }
1403
+ if (Array.isArray(value)) {
1404
+ const displayValue = value.map((item) => typeof item === "object" ? JSON.stringify(item) : String(item)).join(", ");
1405
+ return /* @__PURE__ */ jsxs5(Fragment7, { children: [
1406
+ /* @__PURE__ */ jsx17("span", { style: styles.label, children: label }),
1407
+ /* @__PURE__ */ jsx17("div", { style: styles.value, children: displayValue })
1408
+ ] });
1409
+ }
1410
+ if (type === "COMPLEX" && typeof value === "object") {
1411
+ return /* @__PURE__ */ jsx17(ObjectDisplay, { data: value });
1412
+ }
1413
+ if (isEditing && onEditValue && mutability !== "READ_ONLY") {
1414
+ const fieldValue = editedUser && name && editedUser[name] !== void 0 ? editedUser[name] : value || "";
1415
+ const commonProps = {
1416
+ label: void 0,
1417
+ // Don't show label in field, we render it outside
1418
+ required,
1419
+ value: fieldValue,
1420
+ onChange: (e) => onEditValue(e.target ? e.target.value : e),
1421
+ style: {
1422
+ marginBottom: 0
1423
+ }
1424
+ };
1425
+ let field;
1426
+ switch (type) {
1427
+ case "STRING":
1428
+ field = /* @__PURE__ */ jsx17(TextField, { ...commonProps });
1429
+ break;
1430
+ case "DATE_TIME":
1431
+ field = /* @__PURE__ */ jsx17(DatePicker, { ...commonProps });
1432
+ break;
1433
+ case "BOOLEAN":
1434
+ field = /* @__PURE__ */ jsx17(Checkbox, { ...commonProps, checked: !!fieldValue, onChange: (e) => onEditValue(e.target.checked) });
1435
+ break;
1436
+ case "COMPLEX":
1437
+ field = /* @__PURE__ */ jsx17(TextField, { ...commonProps });
1438
+ break;
1439
+ default:
1440
+ field = /* @__PURE__ */ jsx17(TextField, { ...commonProps });
1441
+ }
1442
+ return /* @__PURE__ */ jsxs5(Fragment7, { children: [
1443
+ /* @__PURE__ */ jsx17("span", { style: styles.label, children: label }),
1444
+ /* @__PURE__ */ jsx17("div", { style: styles.value, children: field })
1445
+ ] });
1446
+ }
1447
+ return /* @__PURE__ */ jsxs5(Fragment7, { children: [
1448
+ /* @__PURE__ */ jsx17("span", { style: styles.label, children: label }),
1449
+ /* @__PURE__ */ jsx17("div", { style: styles.value, children: String(value) })
1450
+ ] });
1451
+ };
1452
+ const renderUserInfo = (schema) => {
1453
+ if (!schema || !schema.name) return null;
1454
+ const isFieldEditing = editingFields[schema.name];
1455
+ const fieldStyle = {
1456
+ ...styles.field,
1457
+ display: "flex",
1458
+ alignItems: "center",
1459
+ gap: theme.spacing.unit + "px"
1460
+ };
1461
+ const actionButtonStyle = {
1462
+ ...buttonStyle,
1463
+ padding: `${theme.spacing.unit / 2}px ${theme.spacing.unit}px`,
1464
+ fontSize: "0.75rem",
1465
+ marginLeft: "auto"
1466
+ };
1467
+ return /* @__PURE__ */ jsxs5("div", { style: fieldStyle, children: [
1468
+ /* @__PURE__ */ jsx17("div", { style: { flex: 1, display: "flex", alignItems: "center", gap: theme.spacing.unit + "px" }, children: renderSchemaField(schema, isFieldEditing, (value) => {
1469
+ const tempEditedUser = { ...editedUser };
1470
+ tempEditedUser[schema.name] = value;
1471
+ setEditedUser(tempEditedUser);
1472
+ }) }),
1473
+ editable && schema.mutability !== "READ_ONLY" && /* @__PURE__ */ jsx17(
1474
+ "div",
1475
+ {
1476
+ style: {
1477
+ display: "flex",
1478
+ gap: theme.spacing.unit / 2 + "px",
1479
+ alignItems: "center",
1480
+ marginLeft: theme.spacing.unit + "px"
1481
+ },
1482
+ children: isFieldEditing ? /* @__PURE__ */ jsxs5(Fragment7, { children: [
1483
+ /* @__PURE__ */ jsx17("button", { style: { ...actionButtonStyle, ...saveButtonStyle }, onClick: () => handleFieldSave(schema), children: "Save" }),
1484
+ /* @__PURE__ */ jsx17(
1485
+ "button",
1486
+ {
1487
+ style: { ...actionButtonStyle, ...cancelButtonStyle },
1488
+ onClick: () => handleFieldCancel(schema.name),
1489
+ children: "Cancel"
1490
+ }
1491
+ )
1492
+ ] }) : /* @__PURE__ */ jsx17(
1493
+ "button",
1494
+ {
1495
+ style: {
1496
+ ...actionButtonStyle,
1497
+ backgroundColor: "transparent",
1498
+ border: "none",
1499
+ margin: 0,
1500
+ padding: theme.spacing.unit / 2 + "px",
1501
+ color: theme.colors.text.secondary
1502
+ },
1503
+ onClick: () => toggleFieldEdit(schema.name),
1504
+ title: "Edit",
1505
+ children: /* @__PURE__ */ jsx17(PencilIcon, {})
1506
+ }
1507
+ )
1508
+ }
1509
+ )
1510
+ ] });
1511
+ };
1512
+ const ObjectDisplay = ({ data }) => {
1513
+ if (!data || typeof data !== "object") return null;
1514
+ return /* @__PURE__ */ jsx17("table", { style: { width: "100%", borderCollapse: "collapse" }, children: /* @__PURE__ */ jsx17("tbody", { children: Object.entries(data).map(([key, value]) => /* @__PURE__ */ jsxs5("tr", { style: { borderBottom: `1px solid ${theme.colors.border}` }, children: [
1515
+ /* @__PURE__ */ jsx17("td", { style: { padding: theme.spacing.unit + "px", verticalAlign: "top" }, children: /* @__PURE__ */ jsxs5("strong", { children: [
1516
+ formatLabel(key),
1517
+ ":"
1518
+ ] }) }),
1519
+ /* @__PURE__ */ jsx17("td", { style: { padding: theme.spacing.unit + "px", verticalAlign: "top" }, children: typeof value === "object" ? /* @__PURE__ */ jsx17(ObjectDisplay, { data: value }) : String(value) })
1520
+ ] }, key)) }) });
1521
+ };
1522
+ const getDisplayName = () => {
1523
+ const firstName = getMappedUserProfileValue_default("firstName", mergedMappings, user);
1524
+ const lastName = getMappedUserProfileValue_default("lastName", mergedMappings, user);
1525
+ if (firstName && lastName) {
1526
+ return `${firstName} ${lastName}`;
1527
+ }
1528
+ return getMappedUserProfileValue_default("username", mergedMappings, user) || "";
1529
+ };
1530
+ if (!user) {
1531
+ return fallback;
1532
+ }
1533
+ const containerStyle = {
1534
+ ...styles.root,
1535
+ ...cardLayout ? styles.card : {}
1536
+ };
1537
+ const avatarAttributes = ["picture"];
1538
+ const excludedProps = avatarAttributes.map((attr) => mergedMappings[attr] || attr);
1539
+ const profileContent = /* @__PURE__ */ jsxs5("div", { style: containerStyle, className: clsx9(withVendorCSSClassPrefix6("user-profile"), className), children: [
1540
+ /* @__PURE__ */ jsx17("div", { style: styles.header, children: /* @__PURE__ */ jsx17(
1541
+ Avatar,
1542
+ {
1543
+ imageUrl: getMappedUserProfileValue_default("picture", mergedMappings, user),
1544
+ name: getDisplayName(),
1545
+ size: 80,
1546
+ alt: `${getDisplayName()}'s avatar`
1547
+ }
1548
+ ) }),
1549
+ /* @__PURE__ */ jsx17("div", { style: styles.infoContainer, children: Array.isArray(user) ? user.filter((schema) => !excludedProps.includes(schema.name) && schema.value).map((schema, index) => /* @__PURE__ */ jsx17("div", { children: renderUserInfo(schema) }, index)) : Object.entries(user).filter(([key]) => !excludedProps.includes(key) && user[key]).map(
1550
+ ([key, value]) => renderUserInfo({
1551
+ name: key,
1552
+ value,
1553
+ displayName: formatLabel(key)
1554
+ })
1555
+ ) })
1556
+ ] });
1557
+ if (mode === "popup") {
1558
+ return /* @__PURE__ */ jsxs5(Popover, { isOpen, onClose: () => setIsOpen(false), portalId, children: [
1559
+ /* @__PURE__ */ jsx17(Popover.Header, { children: title }),
1560
+ /* @__PURE__ */ jsx17(Popover.Content, { children: profileContent })
1561
+ ] });
1562
+ }
1563
+ return profileContent;
1564
+ };
1565
+ var useStyles3 = () => {
1566
+ const { theme, colorScheme } = useTheme();
1567
+ return useMemo5(
1568
+ () => ({
1569
+ root: {
1570
+ padding: theme.spacing.unit * 4 + "px",
1571
+ minWidth: "600px",
1572
+ margin: "0 auto"
1573
+ },
1574
+ card: {
1575
+ background: theme.colors.surface,
1576
+ borderRadius: theme.borderRadius.large
1577
+ },
1578
+ header: {
1579
+ display: "flex",
1580
+ alignItems: "center",
1581
+ gap: theme.spacing.unit * 1.5 + "px",
1582
+ marginBottom: theme.spacing.unit * 1.5 + "px"
1583
+ },
1584
+ profileInfo: {
1585
+ flex: 1
1586
+ },
1587
+ name: {
1588
+ fontSize: "1.5rem",
1589
+ fontWeight: 600,
1590
+ margin: "0",
1591
+ color: theme.colors.text.primary
1592
+ },
1593
+ infoContainer: {
1594
+ display: "flex",
1595
+ flexDirection: "column",
1596
+ gap: theme.spacing.unit + "px"
1597
+ },
1598
+ field: {
1599
+ display: "flex",
1600
+ alignItems: "center",
1601
+ padding: theme.spacing.unit + "px 0",
1602
+ borderBottom: `1px solid ${theme.colors.border}`,
1603
+ minHeight: "32px"
1604
+ },
1605
+ lastField: {
1606
+ borderBottom: "none"
1607
+ },
1608
+ label: {
1609
+ fontSize: "0.875rem",
1610
+ fontWeight: 500,
1611
+ color: theme.colors.text.secondary,
1612
+ width: "120px",
1613
+ flexShrink: 0,
1614
+ lineHeight: "32px"
1615
+ },
1616
+ value: {
1617
+ color: theme.colors.text.primary,
1618
+ flex: 1,
1619
+ display: "flex",
1620
+ alignItems: "center",
1621
+ gap: theme.spacing.unit + "px",
1622
+ overflow: "hidden",
1623
+ minHeight: "32px",
1624
+ "& input, & .MuiInputBase-root": {
1625
+ height: "32px",
1626
+ margin: 0
1627
+ },
1628
+ lineHeight: "32px",
1629
+ "& table": {
1630
+ backgroundColor: theme.colors.background,
1631
+ borderRadius: theme.borderRadius.small,
1632
+ whiteSpace: "normal"
1633
+ },
1634
+ "& td": {
1635
+ borderColor: theme.colors.border
1636
+ }
1637
+ },
1638
+ popup: {
1639
+ padding: theme.spacing.unit * 2 + "px"
1640
+ }
1641
+ }),
1642
+ [theme, colorScheme]
1643
+ );
1644
+ };
1645
+ var BaseUserProfile_default = BaseUserProfile;
1646
+
1647
+ // src/api/scim2/updateMeProfile.ts
1648
+ import { AsgardeoAPIError as AsgardeoAPIError4, AsgardeoSPAClient as AsgardeoSPAClient4 } from "@asgardeo/browser";
1649
+ var httpClient3 = AsgardeoSPAClient4.getInstance().httpRequest.bind(AsgardeoSPAClient4.getInstance());
1650
+ var updateMeProfile = async ({
1651
+ url,
1652
+ payload,
1653
+ ...requestConfig
1654
+ }) => {
1655
+ try {
1656
+ new URL(url);
1657
+ } catch (error) {
1658
+ throw new AsgardeoAPIError4(
1659
+ "Invalid endpoint URL provided",
1660
+ "updateMeProfile-ValidationError-001",
1661
+ "javascript",
1662
+ 400,
1663
+ "Invalid Request"
1664
+ );
1665
+ }
1666
+ const data = {
1667
+ Operations: [
1668
+ {
1669
+ op: "replace",
1670
+ value: payload
1671
+ }
1672
+ ],
1673
+ schemas: ["urn:ietf:params:scim:api:messages:2.0:PatchOp"]
1674
+ };
1675
+ const response = await httpClient3({
1676
+ url,
1677
+ method: "PATCH",
1678
+ headers: {
1679
+ "Content-Type": "application/scim+json",
1680
+ Accept: "application/json"
1681
+ },
1682
+ data,
1683
+ ...requestConfig
1684
+ });
1685
+ if (!response.data) {
1686
+ const errorText = await response.text();
1687
+ throw new AsgardeoAPIError4(
1688
+ `Failed to update user profile: ${errorText}`,
1689
+ "updateMeProfile-ResponseError-001",
1690
+ "javascript",
1691
+ response.status,
1692
+ response.statusText
1693
+ );
1694
+ }
1695
+ return response.data;
1696
+ };
1697
+ var updateMeProfile_default = updateMeProfile;
1698
+
1699
+ // src/components/presentation/UserProfile/UserProfile.tsx
1700
+ import { jsx as jsx18 } from "react/jsx-runtime";
1701
+ var UserProfile = ({ ...rest }) => {
1702
+ const { user, baseUrl } = useAsgardeo_default();
1703
+ const handleProfileUpdate = async (payload) => {
1704
+ await updateMeProfile_default({ url: `${baseUrl}/scim2/Me`, payload });
1705
+ await getMeProfile_default({ url: `${baseUrl}/scim2/Me` });
1706
+ };
1707
+ return /* @__PURE__ */ jsx18(BaseUserProfile_default, { user, onUpdate: handleProfileUpdate, ...rest });
1708
+ };
1709
+ var UserProfile_default = UserProfile;
1710
+
1711
+ // src/components/presentation/UserDropdown/BaseUserDropdown.tsx
1712
+ import { useMemo as useMemo6, useState as useState8 } from "react";
1713
+ import { withVendorCSSClassPrefix as withVendorCSSClassPrefix7 } from "@asgardeo/browser";
1714
+ import clsx10 from "clsx";
1715
+ import { jsx as jsx19, jsxs as jsxs6 } from "react/jsx-runtime";
1716
+ var useStyles4 = () => {
1717
+ const { theme } = useTheme();
1718
+ return useMemo6(
1719
+ () => ({
1720
+ trigger: {
1721
+ display: "inline-flex",
1722
+ alignItems: "center",
1723
+ gap: theme.spacing.unit + "px",
1724
+ padding: theme.spacing.unit * 0.5 + "px",
1725
+ border: "none",
1726
+ background: "none",
1727
+ cursor: "pointer",
1728
+ borderRadius: theme.borderRadius.small,
1729
+ "&:hover": {
1730
+ backgroundColor: theme.colors.background
1731
+ }
1732
+ },
1733
+ userName: {
1734
+ color: theme.colors.text.primary,
1735
+ fontSize: "1rem",
1736
+ fontWeight: 500
1737
+ },
1738
+ dropdownContent: {
1739
+ minWidth: "200px",
1740
+ maxWidth: "300px"
1741
+ },
1742
+ dropdownMenu: {
1743
+ display: "flex",
1744
+ flexDirection: "column",
1745
+ width: "100%"
1746
+ },
1747
+ menuItem: {
1748
+ display: "flex",
1749
+ alignItems: "center",
1750
+ gap: theme.spacing.unit + "px",
1751
+ padding: `${theme.spacing.unit * 2}px ${theme.spacing.unit * 2}px`,
1752
+ width: "100%",
1753
+ color: theme.colors.text.primary,
1754
+ textDecoration: "none",
1755
+ border: "none",
1756
+ background: "none",
1757
+ cursor: "pointer",
1758
+ fontSize: "0.875rem",
1759
+ "&:hover": {
1760
+ backgroundColor: theme.colors.background
1761
+ }
1762
+ },
1763
+ divider: {
1764
+ margin: `${theme.spacing.unit * 0.5}px 0`,
1765
+ borderBottom: `1px solid ${theme.colors.border}`
1766
+ },
1767
+ dropdownHeader: {
1768
+ display: "flex",
1769
+ alignItems: "center",
1770
+ gap: theme.spacing.unit + "px",
1771
+ padding: `${theme.spacing.unit * 1.5}px`,
1772
+ borderBottom: `1px solid ${theme.colors.border}`
1773
+ },
1774
+ headerInfo: {
1775
+ display: "flex",
1776
+ flexDirection: "column",
1777
+ gap: theme.spacing.unit / 2 + "px"
1778
+ },
1779
+ headerName: {
1780
+ color: theme.colors.text.primary,
1781
+ fontSize: "1rem",
1782
+ fontWeight: 500,
1783
+ margin: 0
1784
+ },
1785
+ headerEmail: {
1786
+ color: theme.colors.text.secondary,
1787
+ fontSize: "0.875rem",
1788
+ margin: 0
1789
+ }
1790
+ }),
1791
+ [theme]
1792
+ );
1793
+ };
1794
+ var BaseUserDropdown = ({
1795
+ fallback = /* @__PURE__ */ jsx19("div", { children: "Please sign in" }),
1796
+ className = "",
1797
+ user,
1798
+ portalId = "asgardeo-user-dropdown",
1799
+ menuItems = [],
1800
+ showTriggerLable = false,
1801
+ showDropdownHeader = true,
1802
+ avatarSize = 32,
1803
+ attributeMapping = {}
1804
+ }) => {
1805
+ const styles = useStyles4();
1806
+ const [isOpen, setIsOpen] = useState8(false);
1807
+ const defaultAttributeMappings = {
1808
+ picture: ["profile", "profileUrl"],
1809
+ firstName: "givenName",
1810
+ lastName: "familyName",
1811
+ email: "emails"
1812
+ };
1813
+ const mergedMappings = { ...defaultAttributeMappings, ...attributeMapping };
1814
+ const getDisplayName = () => {
1815
+ const firstName = getMappedUserProfileValue_default("firstName", mergedMappings, user);
1816
+ const lastName = getMappedUserProfileValue_default("lastName", mergedMappings, user);
1817
+ if (firstName && lastName) {
1818
+ return `${firstName} ${lastName}`;
1819
+ }
1820
+ return getMappedUserProfileValue_default("username", mergedMappings, user) || "";
1821
+ };
1822
+ if (!user) {
1823
+ return fallback;
1824
+ }
1825
+ const handleMenuItemClick = (item) => {
1826
+ if (item.onClick) {
1827
+ item.onClick();
1828
+ }
1829
+ setIsOpen(false);
1830
+ };
1831
+ return /* @__PURE__ */ jsxs6("div", { className: clsx10(withVendorCSSClassPrefix7("user-dropdown"), className), children: [
1832
+ /* @__PURE__ */ jsxs6(
1833
+ "button",
1834
+ {
1835
+ className: withVendorCSSClassPrefix7("user-dropdown-trigger"),
1836
+ style: styles.trigger,
1837
+ onClick: () => setIsOpen(!isOpen),
1838
+ children: [
1839
+ /* @__PURE__ */ jsx19(
1840
+ Avatar,
1841
+ {
1842
+ imageUrl: getMappedUserProfileValue_default("picture", mergedMappings, user),
1843
+ name: getDisplayName(),
1844
+ size: avatarSize,
1845
+ alt: `${getDisplayName()}'s avatar`
1846
+ }
1847
+ ),
1848
+ showTriggerLable && /* @__PURE__ */ jsx19("span", { style: styles.userName, children: getDisplayName() })
1849
+ ]
1850
+ }
1851
+ ),
1852
+ /* @__PURE__ */ jsx19(Popover, { isOpen, onClose: () => setIsOpen(false), portalId, mode: "dropdown", children: /* @__PURE__ */ jsx19(Popover.Content, { children: /* @__PURE__ */ jsxs6("div", { style: styles.dropdownContent, children: [
1853
+ showDropdownHeader && /* @__PURE__ */ jsxs6("div", { className: withVendorCSSClassPrefix7("user-dropdown-header"), style: styles.dropdownHeader, children: [
1854
+ /* @__PURE__ */ jsx19(
1855
+ Avatar,
1856
+ {
1857
+ imageUrl: getMappedUserProfileValue_default("picture", mergedMappings, user),
1858
+ name: getDisplayName(),
1859
+ size: avatarSize * 1.25,
1860
+ alt: `${getDisplayName()}'s avatar`
1861
+ }
1862
+ ),
1863
+ /* @__PURE__ */ jsxs6("div", { className: withVendorCSSClassPrefix7("user-dropdown-header-info"), style: styles.headerInfo, children: [
1864
+ /* @__PURE__ */ jsx19("span", { className: withVendorCSSClassPrefix7("user-dropdown-header-name"), style: styles.headerName, children: getDisplayName() }),
1865
+ getMappedUserProfileValue_default("email", mergedMappings, user) !== getDisplayName() && getMappedUserProfileValue_default("email", mergedMappings, user) && /* @__PURE__ */ jsx19(
1866
+ "span",
1867
+ {
1868
+ className: withVendorCSSClassPrefix7("user-dropdown-header-email"),
1869
+ style: styles.headerEmail,
1870
+ children: getMappedUserProfileValue_default("email", mergedMappings, user)
1871
+ }
1872
+ )
1873
+ ] })
1874
+ ] }),
1875
+ /* @__PURE__ */ jsx19("div", { className: withVendorCSSClassPrefix7("user-dropdown-menu"), style: styles.dropdownMenu, children: menuItems.map((item, index) => /* @__PURE__ */ jsxs6("div", { children: [
1876
+ item.href ? /* @__PURE__ */ jsxs6(
1877
+ "a",
1878
+ {
1879
+ href: item.href,
1880
+ style: styles.menuItem,
1881
+ className: withVendorCSSClassPrefix7("user-dropdown-menu-item"),
1882
+ children: [
1883
+ item.icon,
1884
+ item.label
1885
+ ]
1886
+ }
1887
+ ) : /* @__PURE__ */ jsxs6(
1888
+ "button",
1889
+ {
1890
+ onClick: () => handleMenuItemClick(item),
1891
+ style: styles.menuItem,
1892
+ className: withVendorCSSClassPrefix7("user-dropdown-menu-item"),
1893
+ children: [
1894
+ item.icon,
1895
+ item.label
1896
+ ]
1897
+ }
1898
+ ),
1899
+ index < menuItems.length - 1 && /* @__PURE__ */ jsx19("div", { style: styles.divider })
1900
+ ] }, index)) })
1901
+ ] }) }) })
1902
+ ] });
1903
+ };
1904
+ var BaseUserDropdown_default = BaseUserDropdown;
1905
+
1906
+ // src/components/presentation/UserDropdown/UserDropdown.tsx
1907
+ import { jsx as jsx20 } from "react/jsx-runtime";
1908
+ var UserDropdown = ({ ...rest }) => {
1909
+ const { user } = useAsgardeo_default();
1910
+ return /* @__PURE__ */ jsx20(BaseUserDropdown_default, { user, ...rest });
1911
+ };
1912
+ var UserDropdown_default = UserDropdown;
1913
+
1914
+ // src/index.ts
1915
+ export * from "@asgardeo/browser";
1916
+ export {
1917
+ AsgardeoContext_default as AsgardeoContext,
1918
+ AsgardeoProvider_default as AsgardeoProvider,
1919
+ BaseSignInButton_default as BaseSignInButton,
1920
+ BaseSignOutButton_default as BaseSignOutButton,
1921
+ BaseSignUpButton_default as BaseSignUpButton,
1922
+ BaseUserDropdown_default as BaseUserDropdown,
1923
+ BaseUserProfile_default as BaseUserProfile,
1924
+ SignInButton_default as SignInButton,
1925
+ SignOutButton_default as SignOutButton,
1926
+ SignUpButton_default as SignUpButton,
1927
+ SignedIn_default as SignedIn,
1928
+ SignedOut_default as SignedOut,
1929
+ User_default as User,
1930
+ UserDropdown_default as UserDropdown,
1931
+ UserProfile_default as UserProfile,
1932
+ useAsgardeo_default as useAsgardeo,
1933
+ useBrowserUrl_default as useBrowserUrl
1934
+ };
1935
+ //# sourceMappingURL=index.js.map