@strands.gg/accui 1.2.0 → 1.2.1

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.
@@ -9198,6 +9198,7 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
9198
9198
  const emit = __emit;
9199
9199
  const { getSupportEmail, config: strandsConfig, getUrl } = useStrandsConfig(props.config);
9200
9200
  const { fetchProfile, updateProfile, changeEmail, currentUser: authUser, currentSession, isAuthenticated, refreshToken, signOut } = useStrandsAuth();
9201
+ const { mfaDevices: mfaDevices2, mfaEnabled: mfaEnabled2, activeMfaDevices, fetchMfaDevices } = useStrandsMfa();
9201
9202
  const internalUser = ref(null);
9202
9203
  const fetchingProfile = ref(false);
9203
9204
  const currentUser = computed(() => {
@@ -9275,6 +9276,54 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
9275
9276
  const years = Math.floor(diffDays / 365);
9276
9277
  return years === 1 ? "1 year ago" : `${years} years ago`;
9277
9278
  });
9279
+ const deviceTypeCounts = computed(() => {
9280
+ const devices = activeMfaDevices.value || [];
9281
+ const counts = {
9282
+ totp: 0,
9283
+ email: 0,
9284
+ hardware: 0,
9285
+ passkey: 0
9286
+ };
9287
+ devices.forEach((device) => {
9288
+ if (device.device_type in counts) {
9289
+ counts[device.device_type]++;
9290
+ }
9291
+ });
9292
+ return counts;
9293
+ });
9294
+ const mfaDeviceChips = computed(() => {
9295
+ const chips = [];
9296
+ const counts = deviceTypeCounts.value;
9297
+ if (counts.totp > 0) {
9298
+ chips.push({
9299
+ type: "totp",
9300
+ count: counts.totp,
9301
+ label: counts.totp === 1 ? "Auth app" : "Auth apps",
9302
+ icon: Smartphone,
9303
+ color: "bg-blue-50 text-blue-700 border-blue-200"
9304
+ });
9305
+ }
9306
+ if (counts.email > 0) {
9307
+ chips.push({
9308
+ type: "email",
9309
+ count: counts.email,
9310
+ label: "Email",
9311
+ icon: Mail,
9312
+ color: "bg-green-50 text-green-700 border-green-200"
9313
+ });
9314
+ }
9315
+ if (counts.hardware > 0 || counts.passkey > 0) {
9316
+ const totalHardware = counts.hardware + counts.passkey;
9317
+ chips.push({
9318
+ type: "hardware",
9319
+ count: totalHardware,
9320
+ label: totalHardware === 1 ? "Key" : "Keys",
9321
+ icon: KeyRound,
9322
+ color: "bg-purple-50 text-purple-700 border-purple-200"
9323
+ });
9324
+ }
9325
+ return chips;
9326
+ });
9278
9327
  const getInitials2 = (firstName, lastName) => {
9279
9328
  if (!firstName && !lastName) return "U";
9280
9329
  return `${firstName?.[0] || ""}${lastName?.[0] || ""}`.toUpperCase();
@@ -9284,6 +9333,9 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
9284
9333
  fetchingProfile.value = true;
9285
9334
  try {
9286
9335
  await fetchProfile();
9336
+ if (isAuthenticated.value) {
9337
+ await fetchMfaDevices();
9338
+ }
9287
9339
  } catch (err) {
9288
9340
  const errorMsg = err instanceof Error ? err.message : "Failed to load profile";
9289
9341
  errorMessage.value = errorMsg;
@@ -9498,6 +9550,7 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
9498
9550
  const handleMfaUpdated = async () => {
9499
9551
  try {
9500
9552
  await fetchProfile();
9553
+ await fetchMfaDevices();
9501
9554
  successMessage.value = "MFA settings updated successfully";
9502
9555
  emit("mfa-toggle", currentUser.value?.mfaEnabled || false);
9503
9556
  } catch (err) {
@@ -9535,7 +9588,7 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
9535
9588
  signingOut.value = false;
9536
9589
  }
9537
9590
  };
9538
- const __returned__ = { props, emit, getSupportEmail, strandsConfig, getUrl, fetchProfile, updateProfile, changeEmail, authUser, currentSession, isAuthenticated, refreshToken, signOut, internalUser, fetchingProfile, currentUser, loading: loading2, uploading, signingOut, showPasswordChange, showEmailChange, emailChangeLoading, showMfaModal, successMessage, errorMessage, activeSessions, fileInputRef, form, emailChangeForm, passwordForm, errors, hasChanges, isPasswordFormValid, isEmailChangeFormValid, passwordLastUpdated, getInitials: getInitials2, fetchUserProfile, clearMessages, handleUpdateProfile, handlePasswordChange, handleEmailChange, triggerFileUpload, handleFileSelect, uploadAvatar, handleMfaUpdated, handleCancel, handleSignOut, get StrandsUiButton() {
9591
+ const __returned__ = { props, emit, getSupportEmail, strandsConfig, getUrl, fetchProfile, updateProfile, changeEmail, authUser, currentSession, isAuthenticated, refreshToken, signOut, mfaDevices: mfaDevices2, mfaEnabled: mfaEnabled2, activeMfaDevices, fetchMfaDevices, internalUser, fetchingProfile, currentUser, loading: loading2, uploading, signingOut, showPasswordChange, showEmailChange, emailChangeLoading, showMfaModal, successMessage, errorMessage, activeSessions, fileInputRef, form, emailChangeForm, passwordForm, errors, hasChanges, isPasswordFormValid, isEmailChangeFormValid, passwordLastUpdated, deviceTypeCounts, mfaDeviceChips, getInitials: getInitials2, fetchUserProfile, clearMessages, handleUpdateProfile, handlePasswordChange, handleEmailChange, triggerFileUpload, handleFileSelect, uploadAvatar, handleMfaUpdated, handleCancel, handleSignOut, get StrandsUiButton() {
9539
9592
  return StrandsUiButton;
9540
9593
  }, get StrandsUiInput() {
9541
9594
  return StrandsUiInput;
@@ -9588,31 +9641,37 @@ const _hoisted_21 = {
9588
9641
  class: "space-y-3 overflow-hidden"
9589
9642
  };
9590
9643
  const _hoisted_22 = { class: "p-4 bg-gray-50 rounded-xl" };
9591
- const _hoisted_23 = { class: "flex items-center justify-between gap-2" };
9592
- const _hoisted_24 = { class: "text-sm text-gray-600" };
9593
- const _hoisted_25 = { class: "p-4 bg-gray-50 rounded-xl" };
9594
- const _hoisted_26 = { class: "flex items-center justify-between gap-2" };
9595
- const _hoisted_27 = { class: "text-sm text-gray-600" };
9596
- const _hoisted_28 = {
9644
+ const _hoisted_23 = { class: "flex items-start justify-between gap-4" };
9645
+ const _hoisted_24 = { class: "flex-1" };
9646
+ const _hoisted_25 = { class: "text-sm text-gray-600 mt-1" };
9647
+ const _hoisted_26 = {
9648
+ key: 0,
9649
+ class: "flex flex-wrap gap-2 mt-3"
9650
+ };
9651
+ const _hoisted_27 = { class: "ml-1" };
9652
+ const _hoisted_28 = { class: "p-4 bg-gray-50 rounded-xl" };
9653
+ const _hoisted_29 = { class: "flex items-center justify-between gap-2" };
9654
+ const _hoisted_30 = { class: "text-sm text-gray-600" };
9655
+ const _hoisted_31 = {
9597
9656
  key: 0,
9598
9657
  class: "flex flex-col sm:flex-row gap-3 pt-6 border-t border-gray-200 animate-slide-up"
9599
9658
  };
9600
- const _hoisted_29 = {
9659
+ const _hoisted_32 = {
9601
9660
  key: 0,
9602
9661
  class: "mt-6 animate-fade-in"
9603
9662
  };
9604
- const _hoisted_30 = { class: "alert-success" };
9605
- const _hoisted_31 = { class: "flex items-start gap-3" };
9606
- const _hoisted_32 = { class: "font-medium" };
9607
- const _hoisted_33 = {
9663
+ const _hoisted_33 = { class: "alert-success" };
9664
+ const _hoisted_34 = { class: "flex items-start gap-3" };
9665
+ const _hoisted_35 = { class: "font-medium" };
9666
+ const _hoisted_36 = {
9608
9667
  key: 1,
9609
9668
  class: "mt-6 animate-fade-in"
9610
9669
  };
9611
- const _hoisted_34 = { class: "alert-error" };
9612
- const _hoisted_35 = { class: "flex items-start gap-3" };
9613
- const _hoisted_36 = { class: "font-medium" };
9614
- const _hoisted_37 = { key: 0 };
9615
- const _hoisted_38 = { class: "text-gray-400 text-sm" };
9670
+ const _hoisted_37 = { class: "alert-error" };
9671
+ const _hoisted_38 = { class: "flex items-start gap-3" };
9672
+ const _hoisted_39 = { class: "font-medium" };
9673
+ const _hoisted_40 = { key: 0 };
9674
+ const _hoisted_41 = { class: "text-gray-400 text-sm" };
9616
9675
  function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
9617
9676
  return openBlock(), createElementBlock("div", _hoisted_1$5, [
9618
9677
  createElementVNode("div", _hoisted_2$4, [
@@ -9909,7 +9968,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
9909
9968
  createCommentVNode(" Two-Factor Authentication "),
9910
9969
  createElementVNode("div", _hoisted_22, [
9911
9970
  createElementVNode("div", _hoisted_23, [
9912
- createElementVNode("div", null, [
9971
+ createElementVNode("div", _hoisted_24, [
9913
9972
  _cache[17] || (_cache[17] = createElementVNode(
9914
9973
  "h4",
9915
9974
  { class: "font-medium text-gray-900" },
@@ -9919,16 +9978,60 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
9919
9978
  )),
9920
9979
  createElementVNode(
9921
9980
  "p",
9922
- _hoisted_24,
9981
+ _hoisted_25,
9923
9982
  toDisplayString($setup.currentUser?.mfaEnabled ? "Enabled" : "Add extra security to your account"),
9924
9983
  1
9925
9984
  /* TEXT */
9926
- )
9985
+ ),
9986
+ createCommentVNode(" Device Type Chips "),
9987
+ $setup.mfaDeviceChips.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_26, [
9988
+ (openBlock(true), createElementBlock(
9989
+ Fragment,
9990
+ null,
9991
+ renderList($setup.mfaDeviceChips, (chip) => {
9992
+ return openBlock(), createElementBlock(
9993
+ "div",
9994
+ {
9995
+ key: chip.type,
9996
+ class: normalizeClass([
9997
+ "inline-flex items-center px-2.5 py-1 rounded-lg text-xs font-medium border transition-colors",
9998
+ chip.color
9999
+ ])
10000
+ },
10001
+ [
10002
+ (openBlock(), createBlock(resolveDynamicComponent(chip.icon), {
10003
+ size: 12,
10004
+ class: "mr-1.5"
10005
+ })),
10006
+ createElementVNode(
10007
+ "span",
10008
+ null,
10009
+ toDisplayString(chip.count),
10010
+ 1
10011
+ /* TEXT */
10012
+ ),
10013
+ createElementVNode(
10014
+ "span",
10015
+ _hoisted_27,
10016
+ toDisplayString(chip.label),
10017
+ 1
10018
+ /* TEXT */
10019
+ )
10020
+ ],
10021
+ 2
10022
+ /* CLASS */
10023
+ );
10024
+ }),
10025
+ 128
10026
+ /* KEYED_FRAGMENT */
10027
+ ))
10028
+ ])) : createCommentVNode("v-if", true)
9927
10029
  ]),
9928
10030
  createVNode($setup["StrandsUiButton"], {
9929
10031
  variant: $setup.currentUser?.mfaEnabled ? "secondary" : "primary",
9930
10032
  size: "sm",
9931
- onClick: _cache[9] || (_cache[9] = ($event) => $setup.showMfaModal = true)
10033
+ onClick: _cache[9] || (_cache[9] = ($event) => $setup.showMfaModal = true),
10034
+ class: "flex-shrink-0"
9932
10035
  }, {
9933
10036
  default: withCtx(() => [
9934
10037
  createTextVNode(
@@ -9943,8 +10046,8 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
9943
10046
  ])
9944
10047
  ]),
9945
10048
  createCommentVNode(" Active Sessions "),
9946
- createElementVNode("div", _hoisted_25, [
9947
- createElementVNode("div", _hoisted_26, [
10049
+ createElementVNode("div", _hoisted_28, [
10050
+ createElementVNode("div", _hoisted_29, [
9948
10051
  createElementVNode("div", null, [
9949
10052
  _cache[18] || (_cache[18] = createElementVNode(
9950
10053
  "h4",
@@ -9955,7 +10058,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
9955
10058
  )),
9956
10059
  createElementVNode(
9957
10060
  "p",
9958
- _hoisted_27,
10061
+ _hoisted_30,
9959
10062
  toDisplayString($setup.activeSessions.length) + " active device(s)",
9960
10063
  1
9961
10064
  /* TEXT */
@@ -9982,7 +10085,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
9982
10085
  ])
9983
10086
  ]),
9984
10087
  createCommentVNode(" Action Buttons - Only show when changes are made "),
9985
- $setup.hasChanges ? (openBlock(), createElementBlock("div", _hoisted_28, [
10088
+ $setup.hasChanges ? (openBlock(), createElementBlock("div", _hoisted_31, [
9986
10089
  createVNode($setup["StrandsUiButton"], {
9987
10090
  type: "submit",
9988
10091
  variant: "primary",
@@ -10020,9 +10123,9 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
10020
10123
  /* NEED_HYDRATION */
10021
10124
  ),
10022
10125
  createCommentVNode(" Success/Error Messages "),
10023
- $setup.successMessage ? (openBlock(), createElementBlock("div", _hoisted_29, [
10024
- createElementVNode("div", _hoisted_30, [
10025
- createElementVNode("div", _hoisted_31, [
10126
+ $setup.successMessage ? (openBlock(), createElementBlock("div", _hoisted_32, [
10127
+ createElementVNode("div", _hoisted_33, [
10128
+ createElementVNode("div", _hoisted_34, [
10026
10129
  _cache[22] || (_cache[22] = createElementVNode(
10027
10130
  "svg",
10028
10131
  {
@@ -10042,7 +10145,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
10042
10145
  )),
10043
10146
  createElementVNode(
10044
10147
  "p",
10045
- _hoisted_32,
10148
+ _hoisted_35,
10046
10149
  toDisplayString($setup.successMessage),
10047
10150
  1
10048
10151
  /* TEXT */
@@ -10050,9 +10153,9 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
10050
10153
  ])
10051
10154
  ])
10052
10155
  ])) : createCommentVNode("v-if", true),
10053
- $setup.errorMessage ? (openBlock(), createElementBlock("div", _hoisted_33, [
10054
- createElementVNode("div", _hoisted_34, [
10055
- createElementVNode("div", _hoisted_35, [
10156
+ $setup.errorMessage ? (openBlock(), createElementBlock("div", _hoisted_36, [
10157
+ createElementVNode("div", _hoisted_37, [
10158
+ createElementVNode("div", _hoisted_38, [
10056
10159
  _cache[23] || (_cache[23] = createElementVNode(
10057
10160
  "svg",
10058
10161
  {
@@ -10072,7 +10175,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
10072
10175
  )),
10073
10176
  createElementVNode(
10074
10177
  "p",
10075
- _hoisted_36,
10178
+ _hoisted_39,
10076
10179
  toDisplayString($setup.errorMessage),
10077
10180
  1
10078
10181
  /* TEXT */
@@ -10103,8 +10206,8 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
10103
10206
  /* STABLE */
10104
10207
  }, 8, ["disabled"]),
10105
10208
  createCommentVNode(" Need help "),
10106
- $setup.getSupportEmail() ? (openBlock(), createElementBlock("div", _hoisted_37, [
10107
- createElementVNode("p", _hoisted_38, [
10209
+ $setup.getSupportEmail() ? (openBlock(), createElementBlock("div", _hoisted_40, [
10210
+ createElementVNode("p", _hoisted_41, [
10108
10211
  _cache[25] || (_cache[25] = createTextVNode(
10109
10212
  " Need help? ",
10110
10213
  -1