@strands.gg/accui 1.1.4 → 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.
@@ -1476,37 +1476,37 @@ const _hoisted_14$9 = { class: "flex items-center space-x-3" };
1476
1476
  const _hoisted_15$9 = { class: "text-2xl" };
1477
1477
  const _hoisted_16$8 = { class: "font-medium text-gray-900" };
1478
1478
  const _hoisted_17$7 = { class: "text-sm text-gray-500" };
1479
- const _hoisted_18$5 = {
1479
+ const _hoisted_18$6 = {
1480
1480
  key: 2,
1481
1481
  class: "text-center"
1482
1482
  };
1483
- const _hoisted_19$3 = {
1483
+ const _hoisted_19$5 = {
1484
1484
  key: 3,
1485
1485
  class: "text-center space-y-4"
1486
1486
  };
1487
- const _hoisted_20$2 = {
1487
+ const _hoisted_20$3 = {
1488
1488
  key: 4,
1489
1489
  class: "space-y-4"
1490
1490
  };
1491
- const _hoisted_21$2 = {
1491
+ const _hoisted_21$3 = {
1492
1492
  key: 0,
1493
1493
  class: "bg-green-50 border border-green-200 rounded-lg p-4"
1494
1494
  };
1495
- const _hoisted_22$2 = {
1495
+ const _hoisted_22$3 = {
1496
1496
  key: 1,
1497
1497
  class: "text-sm text-gray-600"
1498
1498
  };
1499
- const _hoisted_23$1 = {
1499
+ const _hoisted_23$2 = {
1500
1500
  key: 2,
1501
1501
  class: "flex justify-between text-sm"
1502
1502
  };
1503
- const _hoisted_24$1 = ["disabled"];
1504
- const _hoisted_25$1 = { class: "pt-4 border-t border-gray-200" };
1505
- const _hoisted_26$1 = {
1503
+ const _hoisted_24$2 = ["disabled"];
1504
+ const _hoisted_25$2 = { class: "pt-4 border-t border-gray-200" };
1505
+ const _hoisted_26$2 = {
1506
1506
  key: 3,
1507
1507
  class: "space-y-4"
1508
1508
  };
1509
- const _hoisted_27$1 = { class: "flex justify-between" };
1509
+ const _hoisted_27$2 = { class: "flex justify-between" };
1510
1510
  function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
1511
1511
  return vue.openBlock(), vue.createBlock($setup["UiModal"], {
1512
1512
  open: $props.show,
@@ -1525,7 +1525,7 @@ function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
1525
1525
  )
1526
1526
  ])),
1527
1527
  footer: vue.withCtx(() => [
1528
- vue.createElementVNode("div", _hoisted_27$1, [
1528
+ vue.createElementVNode("div", _hoisted_27$2, [
1529
1529
  vue.createVNode($setup["StrandsUiButton"], {
1530
1530
  variant: "secondary",
1531
1531
  onClick: $setup.closeModal,
@@ -1684,7 +1684,7 @@ function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
1684
1684
  /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
1685
1685
  )) : vue.createCommentVNode("v-if", true),
1686
1686
  vue.createCommentVNode(" Email MFA Code Request "),
1687
- $setup.selectedMethod?.device_type === "email" && !$setup.emailCodeSent ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_18$5, [
1687
+ $setup.selectedMethod?.device_type === "email" && !$setup.emailCodeSent ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_18$6, [
1688
1688
  _cache[8] || (_cache[8] = vue.createElementVNode(
1689
1689
  "p",
1690
1690
  { class: "text-sm text-gray-600 mb-4" },
@@ -1710,7 +1710,7 @@ function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
1710
1710
  }, 8, ["disabled", "loading"])
1711
1711
  ])) : vue.createCommentVNode("v-if", true),
1712
1712
  vue.createCommentVNode(" Hardware Key Authentication "),
1713
- $setup.selectedMethod?.device_type === "hardware" ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_19$3, [
1713
+ $setup.selectedMethod?.device_type === "hardware" ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_19$5, [
1714
1714
  _cache[10] || (_cache[10] = vue.createElementVNode(
1715
1715
  "div",
1716
1716
  { class: "bg-blue-50 border border-blue-200 rounded-lg p-4" },
@@ -1758,9 +1758,9 @@ function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
1758
1758
  }, 8, ["disabled", "loading"])
1759
1759
  ])) : vue.createCommentVNode("v-if", true),
1760
1760
  vue.createCommentVNode(" Code Input "),
1761
- $setup.selectedMethod && $setup.selectedMethod.device_type !== "hardware" && ($setup.selectedMethod.device_type !== "email" || $setup.emailCodeSent) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_20$2, [
1761
+ $setup.selectedMethod && $setup.selectedMethod.device_type !== "hardware" && ($setup.selectedMethod.device_type !== "email" || $setup.emailCodeSent) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_20$3, [
1762
1762
  vue.createCommentVNode(" Email confirmation "),
1763
- $setup.selectedMethod.device_type === "email" && $setup.emailCodeSent ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_21$2, _cache[11] || (_cache[11] = [
1763
+ $setup.selectedMethod.device_type === "email" && $setup.emailCodeSent ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_21$3, _cache[11] || (_cache[11] = [
1764
1764
  vue.createElementVNode(
1765
1765
  "div",
1766
1766
  { class: "flex items-start space-x-2" },
@@ -1801,28 +1801,28 @@ function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
1801
1801
  vue.createCommentVNode(" TOTP Help "),
1802
1802
  $setup.selectedMethod.device_type === "totp" ? (vue.openBlock(), vue.createElementBlock(
1803
1803
  "div",
1804
- _hoisted_22$2,
1804
+ _hoisted_22$3,
1805
1805
  ' Open your authenticator app and enter the 6-digit code for "' + vue.toDisplayString($setup.selectedMethod.device_name) + '" ',
1806
1806
  1
1807
1807
  /* TEXT */
1808
1808
  )) : vue.createCommentVNode("v-if", true),
1809
1809
  vue.createCommentVNode(" Email Resend "),
1810
- $setup.selectedMethod.device_type === "email" ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_23$1, [
1810
+ $setup.selectedMethod.device_type === "email" ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_23$2, [
1811
1811
  vue.createElementVNode("button", {
1812
1812
  onClick: $setup.sendEmailCode,
1813
1813
  disabled: $setup.loading || $setup.cooldownActive,
1814
1814
  class: "text-strands-600 hover:text-strands-800 disabled:text-gray-400 disabled:cursor-not-allowed"
1815
- }, vue.toDisplayString($setup.cooldownActive ? `Resend in ${$setup.cooldownSeconds}s` : "Resend Code"), 9, _hoisted_24$1)
1815
+ }, vue.toDisplayString($setup.cooldownActive ? `Resend in ${$setup.cooldownSeconds}s` : "Resend Code"), 9, _hoisted_24$2)
1816
1816
  ])) : vue.createCommentVNode("v-if", true),
1817
1817
  vue.createCommentVNode(" Backup Codes Option "),
1818
- vue.createElementVNode("div", _hoisted_25$1, [
1818
+ vue.createElementVNode("div", _hoisted_25$2, [
1819
1819
  vue.createElementVNode("button", {
1820
1820
  onClick: _cache[1] || (_cache[1] = ($event) => $setup.showBackupCodeInput = !$setup.showBackupCodeInput),
1821
1821
  class: "text-sm text-gray-600 hover:text-gray-800 underline"
1822
1822
  }, " Use backup code instead ")
1823
1823
  ]),
1824
1824
  vue.createCommentVNode(" Backup Code Input "),
1825
- $setup.showBackupCodeInput ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_26$1, [
1825
+ $setup.showBackupCodeInput ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_26$2, [
1826
1826
  vue.createVNode($setup["StrandsUiInput"], {
1827
1827
  modelValue: $setup.backupCode,
1828
1828
  "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => $setup.backupCode = $event),
@@ -3245,11 +3245,11 @@ const _hoisted_15$6 = {
3245
3245
  };
3246
3246
  const _hoisted_16$5 = { class: "alert-error" };
3247
3247
  const _hoisted_17$5 = { class: "flex items-start gap-3" };
3248
- const _hoisted_18$4 = { class: "font-medium" };
3249
- const _hoisted_19$2 = { class: "mt-8 text-center" };
3250
- const _hoisted_20$1 = { class: "text-sm text-neutral-600" };
3251
- const _hoisted_21$1 = { key: 0 };
3252
- const _hoisted_22$1 = { class: "text-neutral-400 text-sm" };
3248
+ const _hoisted_18$5 = { class: "font-medium" };
3249
+ const _hoisted_19$4 = { class: "mt-8 text-center" };
3250
+ const _hoisted_20$2 = { class: "text-sm text-neutral-600" };
3251
+ const _hoisted_21$2 = { key: 0 };
3252
+ const _hoisted_22$2 = { class: "text-neutral-400 text-sm" };
3253
3253
  function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
3254
3254
  return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$d, [
3255
3255
  vue.createCommentVNode(" Success State "),
@@ -3502,7 +3502,7 @@ function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
3502
3502
  )),
3503
3503
  vue.createElementVNode(
3504
3504
  "p",
3505
- _hoisted_18$4,
3505
+ _hoisted_18$5,
3506
3506
  vue.toDisplayString($setup.error),
3507
3507
  1
3508
3508
  /* TEXT */
@@ -3511,8 +3511,8 @@ function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
3511
3511
  ])
3512
3512
  ])) : vue.createCommentVNode("v-if", true),
3513
3513
  vue.createCommentVNode(" Sign in link "),
3514
- vue.createElementVNode("div", _hoisted_19$2, [
3515
- vue.createElementVNode("p", _hoisted_20$1, [
3514
+ vue.createElementVNode("div", _hoisted_19$4, [
3515
+ vue.createElementVNode("p", _hoisted_20$2, [
3516
3516
  _cache[10] || (_cache[10] = vue.createTextVNode(
3517
3517
  " Already have an account? ",
3518
3518
  -1
@@ -3531,8 +3531,8 @@ function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
3531
3531
  }, {
3532
3532
  default: vue.withCtx(() => [
3533
3533
  vue.createCommentVNode(" Need help "),
3534
- $setup.getSupportEmail() ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_21$1, [
3535
- vue.createElementVNode("p", _hoisted_22$1, [
3534
+ $setup.getSupportEmail() ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_21$2, [
3535
+ vue.createElementVNode("p", _hoisted_22$2, [
3536
3536
  _cache[12] || (_cache[12] = vue.createTextVNode(
3537
3537
  " Need help? ",
3538
3538
  -1
@@ -4122,6 +4122,173 @@ function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
4122
4122
  );
4123
4123
  }
4124
4124
  const StrandsCompleteSignUp = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$e], ["__file", "/home/runner/work/strands-accounts/strands-accounts/apps/accounts-ui/src/vue/components/StrandsCompleteSignUp.vue"]]);
4125
+ /**
4126
+ * @license lucide-vue-next v0.539.0 - ISC
4127
+ *
4128
+ * This source code is licensed under the ISC license.
4129
+ * See the LICENSE file in the root directory of this source tree.
4130
+ */
4131
+ const toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
4132
+ const toCamelCase = (string) => string.replace(
4133
+ /^([A-Z])|[\s-_]+(\w)/g,
4134
+ (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()
4135
+ );
4136
+ const toPascalCase = (string) => {
4137
+ const camelCase = toCamelCase(string);
4138
+ return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);
4139
+ };
4140
+ const mergeClasses = (...classes) => classes.filter((className, index, array) => {
4141
+ return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index;
4142
+ }).join(" ").trim();
4143
+ const isEmptyString = (value) => value === "";
4144
+ /**
4145
+ * @license lucide-vue-next v0.539.0 - ISC
4146
+ *
4147
+ * This source code is licensed under the ISC license.
4148
+ * See the LICENSE file in the root directory of this source tree.
4149
+ */
4150
+ var defaultAttributes = {
4151
+ xmlns: "http://www.w3.org/2000/svg",
4152
+ width: 24,
4153
+ height: 24,
4154
+ viewBox: "0 0 24 24",
4155
+ fill: "none",
4156
+ stroke: "currentColor",
4157
+ "stroke-width": 2,
4158
+ "stroke-linecap": "round",
4159
+ "stroke-linejoin": "round"
4160
+ };
4161
+ /**
4162
+ * @license lucide-vue-next v0.539.0 - ISC
4163
+ *
4164
+ * This source code is licensed under the ISC license.
4165
+ * See the LICENSE file in the root directory of this source tree.
4166
+ */
4167
+ const Icon = ({
4168
+ name,
4169
+ iconNode,
4170
+ absoluteStrokeWidth,
4171
+ "absolute-stroke-width": absoluteStrokeWidthKebabCase,
4172
+ strokeWidth,
4173
+ "stroke-width": strokeWidthKebabCase,
4174
+ size = defaultAttributes.width,
4175
+ color = defaultAttributes.stroke,
4176
+ ...props
4177
+ }, { slots }) => {
4178
+ return vue.h(
4179
+ "svg",
4180
+ {
4181
+ ...defaultAttributes,
4182
+ ...props,
4183
+ width: size,
4184
+ height: size,
4185
+ stroke: color,
4186
+ "stroke-width": isEmptyString(absoluteStrokeWidth) || isEmptyString(absoluteStrokeWidthKebabCase) || absoluteStrokeWidth === true || absoluteStrokeWidthKebabCase === true ? Number(strokeWidth || strokeWidthKebabCase || defaultAttributes["stroke-width"]) * 24 / Number(size) : strokeWidth || strokeWidthKebabCase || defaultAttributes["stroke-width"],
4187
+ class: mergeClasses(
4188
+ "lucide",
4189
+ props.class,
4190
+ ...name ? [`lucide-${toKebabCase(toPascalCase(name))}-icon`, `lucide-${toKebabCase(name)}`] : ["lucide-icon"]
4191
+ )
4192
+ },
4193
+ [...iconNode.map((child) => vue.h(...child)), ...slots.default ? [slots.default()] : []]
4194
+ );
4195
+ };
4196
+ /**
4197
+ * @license lucide-vue-next v0.539.0 - ISC
4198
+ *
4199
+ * This source code is licensed under the ISC license.
4200
+ * See the LICENSE file in the root directory of this source tree.
4201
+ */
4202
+ const createLucideIcon = (iconName, iconNode) => (props, { slots, attrs }) => vue.h(
4203
+ Icon,
4204
+ {
4205
+ ...attrs,
4206
+ ...props,
4207
+ iconNode,
4208
+ name: iconName
4209
+ },
4210
+ slots
4211
+ );
4212
+ /**
4213
+ * @license lucide-vue-next v0.539.0 - ISC
4214
+ *
4215
+ * This source code is licensed under the ISC license.
4216
+ * See the LICENSE file in the root directory of this source tree.
4217
+ */
4218
+ const KeyRound = createLucideIcon("key-round", [
4219
+ [
4220
+ "path",
4221
+ {
4222
+ d: "M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z",
4223
+ key: "1s6t7t"
4224
+ }
4225
+ ],
4226
+ ["circle", { cx: "16.5", cy: "7.5", r: ".5", fill: "currentColor", key: "w0ekpg" }]
4227
+ ]);
4228
+ /**
4229
+ * @license lucide-vue-next v0.539.0 - ISC
4230
+ *
4231
+ * This source code is licensed under the ISC license.
4232
+ * See the LICENSE file in the root directory of this source tree.
4233
+ */
4234
+ const Mail = createLucideIcon("mail", [
4235
+ ["path", { d: "m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7", key: "132q7q" }],
4236
+ ["rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", key: "izxlao" }]
4237
+ ]);
4238
+ /**
4239
+ * @license lucide-vue-next v0.539.0 - ISC
4240
+ *
4241
+ * This source code is licensed under the ISC license.
4242
+ * See the LICENSE file in the root directory of this source tree.
4243
+ */
4244
+ const Settings = createLucideIcon("settings", [
4245
+ [
4246
+ "path",
4247
+ {
4248
+ d: "M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915",
4249
+ key: "1i5ecw"
4250
+ }
4251
+ ],
4252
+ ["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }]
4253
+ ]);
4254
+ /**
4255
+ * @license lucide-vue-next v0.539.0 - ISC
4256
+ *
4257
+ * This source code is licensed under the ISC license.
4258
+ * See the LICENSE file in the root directory of this source tree.
4259
+ */
4260
+ const Shield = createLucideIcon("shield", [
4261
+ [
4262
+ "path",
4263
+ {
4264
+ d: "M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",
4265
+ key: "oel41y"
4266
+ }
4267
+ ]
4268
+ ]);
4269
+ /**
4270
+ * @license lucide-vue-next v0.539.0 - ISC
4271
+ *
4272
+ * This source code is licensed under the ISC license.
4273
+ * See the LICENSE file in the root directory of this source tree.
4274
+ */
4275
+ const Smartphone = createLucideIcon("smartphone", [
4276
+ ["rect", { width: "14", height: "20", x: "5", y: "2", rx: "2", ry: "2", key: "1yt0o3" }],
4277
+ ["path", { d: "M12 18h.01", key: "mhygvu" }]
4278
+ ]);
4279
+ /**
4280
+ * @license lucide-vue-next v0.539.0 - ISC
4281
+ *
4282
+ * This source code is licensed under the ISC license.
4283
+ * See the LICENSE file in the root directory of this source tree.
4284
+ */
4285
+ const Trash2 = createLucideIcon("trash-2", [
4286
+ ["path", { d: "M10 11v6", key: "nco0om" }],
4287
+ ["path", { d: "M14 11v6", key: "outv1u" }],
4288
+ ["path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6", key: "miytrc" }],
4289
+ ["path", { d: "M3 6h18", key: "d0wm0j" }],
4290
+ ["path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2", key: "e791ji" }]
4291
+ ]);
4125
4292
  function getDefaultExportFromCjs(x) {
4126
4293
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
4127
4294
  }
@@ -6392,8 +6559,8 @@ const _hoisted_14$5 = {
6392
6559
  const _hoisted_15$5 = { class: "bg-red-50 border border-red-200 rounded-lg p-4" };
6393
6560
  const _hoisted_16$4 = { class: "bg-white rounded border p-3" };
6394
6561
  const _hoisted_17$4 = { class: "grid grid-cols-2 gap-2 text-sm font-mono text-gray-900" };
6395
- const _hoisted_18$3 = { class: "flex justify-center mt-3" };
6396
- const _hoisted_19$1 = { class: "flex justify-end pt-4" };
6562
+ const _hoisted_18$4 = { class: "flex justify-center mt-3" };
6563
+ const _hoisted_19$3 = { class: "flex justify-end pt-4" };
6397
6564
  function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
6398
6565
  return vue.openBlock(), vue.createBlock($setup["UiModal"], {
6399
6566
  open: $props.show,
@@ -6716,7 +6883,7 @@ function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
6716
6883
  ))
6717
6884
  ])
6718
6885
  ]),
6719
- vue.createElementVNode("div", _hoisted_18$3, [
6886
+ vue.createElementVNode("div", _hoisted_18$4, [
6720
6887
  vue.createVNode($setup["StrandsUiButton"], {
6721
6888
  variant: "secondary",
6722
6889
  size: "sm",
@@ -6734,7 +6901,7 @@ function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
6734
6901
  })
6735
6902
  ])
6736
6903
  ]),
6737
- vue.createElementVNode("div", _hoisted_19$1, [
6904
+ vue.createElementVNode("div", _hoisted_19$3, [
6738
6905
  vue.createVNode($setup["StrandsUiButton"], {
6739
6906
  variant: "primary",
6740
6907
  onClick: $setup.finish
@@ -7426,7 +7593,7 @@ const _hoisted_15$4 = {
7426
7593
  };
7427
7594
  const _hoisted_16$3 = { class: "text-center" };
7428
7595
  const _hoisted_17$3 = { class: "text-sm text-gray-600 mb-6" };
7429
- const _hoisted_18$2 = { class: "flex justify-end space-x-3 pt-4" };
7596
+ const _hoisted_18$3 = { class: "flex justify-end space-x-3 pt-4" };
7430
7597
  function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
7431
7598
  return vue.openBlock(), vue.createBlock($setup["UiModal"], {
7432
7599
  open: $props.show,
@@ -7824,7 +7991,7 @@ function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
7824
7991
  /* TEXT */
7825
7992
  )
7826
7993
  ]),
7827
- vue.createElementVNode("div", _hoisted_18$2, [
7994
+ vue.createElementVNode("div", _hoisted_18$3, [
7828
7995
  vue.createVNode($setup["StrandsUiButton"], {
7829
7996
  variant: "secondary",
7830
7997
  onClick: _cache[2] || (_cache[2] = ($event) => $setup.step = 1)
@@ -8386,6 +8553,7 @@ const _sfc_main$8 = /* @__PURE__ */ vue.defineComponent({
8386
8553
  formatLastUsed
8387
8554
  } = useStrandsMfa();
8388
8555
  const showModal = vue.computed(() => props.show);
8556
+ const activeTab = vue.ref("add");
8389
8557
  const showTotpSetup = vue.ref(false);
8390
8558
  const showEmailMfaSetup = vue.ref(false);
8391
8559
  const showHardwareKeySetup = vue.ref(false);
@@ -8445,16 +8613,19 @@ const _sfc_main$8 = /* @__PURE__ */ vue.defineComponent({
8445
8613
  const handleTotpSetupSuccess = async () => {
8446
8614
  showTotpSetup.value = false;
8447
8615
  await fetchMfaDevices();
8616
+ activeTab.value = "manage";
8448
8617
  emit("mfa-updated");
8449
8618
  };
8450
8619
  const handleEmailMfaSetupSuccess = async () => {
8451
8620
  showEmailMfaSetup.value = false;
8452
8621
  await fetchMfaDevices();
8622
+ activeTab.value = "manage";
8453
8623
  emit("mfa-updated");
8454
8624
  };
8455
8625
  const handleHardwareKeySetupSuccess = async () => {
8456
8626
  showHardwareKeySetup.value = false;
8457
8627
  await fetchMfaDevices();
8628
+ activeTab.value = "manage";
8458
8629
  emit("mfa-updated");
8459
8630
  };
8460
8631
  const getDeviceIconBackground = (deviceType) => {
@@ -8470,10 +8641,33 @@ const _sfc_main$8 = /* @__PURE__ */ vue.defineComponent({
8470
8641
  return "bg-gray-50 group-hover:bg-gray-100";
8471
8642
  }
8472
8643
  };
8473
- const __returned__ = { props, emit, mfaDevices: mfaDevices2, mfaEnabled: mfaEnabled2, mfaLoading, activeMfaDevices, fetchMfaDevices, disableMfaDevice, sendEmailMfaCode, getDeviceTypeIcon, getDeviceTypeName, formatLastUsed, showModal, showTotpSetup, showEmailMfaSetup, showHardwareKeySetup, showBackupCodesModal, showConfirmDisable, selectedDevice, closeModal, startTotpSetup, startEmailMfaSetup, startHardwareKeySetup, showBackupCodes, testEmailMfa, confirmDisableDevice, handleDisableDevice, handleTotpSetupSuccess, handleEmailMfaSetupSuccess, handleHardwareKeySetupSuccess, getDeviceIconBackground, get StrandsUiButton() {
8644
+ const getDeviceIconComponent = (deviceType) => {
8645
+ switch (deviceType) {
8646
+ case "totp":
8647
+ return Smartphone;
8648
+ case "email":
8649
+ return Mail;
8650
+ case "hardware":
8651
+ case "passkey":
8652
+ return KeyRound;
8653
+ default:
8654
+ return Shield;
8655
+ }
8656
+ };
8657
+ const __returned__ = { props, emit, mfaDevices: mfaDevices2, mfaEnabled: mfaEnabled2, mfaLoading, activeMfaDevices, fetchMfaDevices, disableMfaDevice, sendEmailMfaCode, getDeviceTypeIcon, getDeviceTypeName, formatLastUsed, showModal, activeTab, showTotpSetup, showEmailMfaSetup, showHardwareKeySetup, showBackupCodesModal, showConfirmDisable, selectedDevice, closeModal, startTotpSetup, startEmailMfaSetup, startHardwareKeySetup, showBackupCodes, testEmailMfa, confirmDisableDevice, handleDisableDevice, handleTotpSetupSuccess, handleEmailMfaSetupSuccess, handleHardwareKeySetupSuccess, getDeviceIconBackground, getDeviceIconComponent, get StrandsUiButton() {
8474
8658
  return StrandsUiButton;
8475
8659
  }, get StrandsUiLoader() {
8476
8660
  return StrandsUiLoader;
8661
+ }, get Smartphone() {
8662
+ return Smartphone;
8663
+ }, get Mail() {
8664
+ return Mail;
8665
+ }, get KeyRound() {
8666
+ return KeyRound;
8667
+ }, get Shield() {
8668
+ return Shield;
8669
+ }, get Trash2() {
8670
+ return Trash2;
8477
8671
  }, UiModal, StrandsTotpSetupModal, StrandsEmailMfaSetupModal, StrandsHardwareKeySetupModal, StrandsBackupCodesModal, StrandsConfirmModal };
8478
8672
  Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
8479
8673
  return __returned__;
@@ -8496,15 +8690,34 @@ const _hoisted_8$2 = {
8496
8690
  key: 1,
8497
8691
  class: "inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-600"
8498
8692
  };
8499
- const _hoisted_9$2 = { key: 0 };
8500
- const _hoisted_10$2 = { class: "space-y-3" };
8501
- const _hoisted_11$2 = { class: "flex items-center space-x-3" };
8502
- const _hoisted_12$2 = { class: "text-xl" };
8503
- const _hoisted_13$2 = { class: "min-w-0 flex-1" };
8504
- const _hoisted_14$2 = { class: "font-medium text-gray-900 text-sm" };
8505
- const _hoisted_15$2 = { class: "text-xs text-gray-500 mt-0.5" };
8506
- const _hoisted_16$2 = { class: "flex items-center space-x-2" };
8507
- const _hoisted_17$2 = { class: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-4" };
8693
+ const _hoisted_9$2 = { class: "border-b border-gray-200" };
8694
+ const _hoisted_10$2 = {
8695
+ class: "-mb-px flex space-x-8",
8696
+ "aria-label": "Tabs"
8697
+ };
8698
+ const _hoisted_11$2 = {
8699
+ key: 0,
8700
+ class: "space-y-6"
8701
+ };
8702
+ const _hoisted_12$2 = { class: "space-y-4" };
8703
+ const _hoisted_13$2 = { class: "flex items-center justify-between" };
8704
+ const _hoisted_14$2 = { class: "flex-shrink-0 w-14 h-14 bg-[var(--strands-primary)] bg-opacity-10 rounded-xl flex items-center justify-center group-hover:bg-[var(--strands-primary)] group-hover:bg-opacity-15 transition-colors" };
8705
+ const _hoisted_15$2 = { class: "flex flex-col space-y-2 ml-4" };
8706
+ const _hoisted_16$2 = { class: "flex items-center justify-between" };
8707
+ const _hoisted_17$2 = { class: "flex-shrink-0 w-14 h-14 bg-[var(--strands-primary)] bg-opacity-10 rounded-xl flex items-center justify-center group-hover:bg-[var(--strands-primary)] group-hover:bg-opacity-15 transition-colors" };
8708
+ const _hoisted_18$2 = { class: "flex flex-col space-y-2 ml-4" };
8709
+ const _hoisted_19$2 = { class: "flex items-center justify-between" };
8710
+ const _hoisted_20$1 = { class: "flex-shrink-0 w-14 h-14 bg-[var(--strands-primary)] bg-opacity-10 rounded-xl flex items-center justify-center group-hover:bg-[var(--strands-primary)] group-hover:bg-opacity-15 transition-colors" };
8711
+ const _hoisted_21$1 = { class: "flex flex-col space-y-2 ml-4" };
8712
+ const _hoisted_22$1 = { class: "space-y-6" };
8713
+ const _hoisted_23$1 = { class: "max-h-96 overflow-y-auto space-y-4 pr-2" };
8714
+ const _hoisted_24$1 = { class: "flex items-start justify-between" };
8715
+ const _hoisted_25$1 = { class: "flex items-start space-x-4" };
8716
+ const _hoisted_26$1 = { class: "min-w-0 flex-1" };
8717
+ const _hoisted_27$1 = { class: "font-semibold text-gray-900 text-lg" };
8718
+ const _hoisted_28$1 = { class: "text-sm text-gray-600 mt-1" };
8719
+ const _hoisted_29$1 = { class: "text-xs text-gray-500 mt-2" };
8720
+ const _hoisted_30$1 = { class: "flex flex-col space-y-2 ml-4" };
8508
8721
  function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
8509
8722
  return vue.openBlock(), vue.createElementBlock(
8510
8723
  vue.Fragment,
@@ -8513,11 +8726,11 @@ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
8513
8726
  vue.createVNode($setup["UiModal"], {
8514
8727
  open: $setup.showModal,
8515
8728
  onClose: $setup.closeModal,
8516
- "card-class": "max-w-lg"
8729
+ "card-class": "max-w-4xl"
8517
8730
  }, {
8518
8731
  header: vue.withCtx(() => [
8519
8732
  vue.createElementVNode("div", { class: "flex items-center justify-between" }, [
8520
- _cache[6] || (_cache[6] = vue.createElementVNode(
8733
+ _cache[8] || (_cache[8] = vue.createElementVNode(
8521
8734
  "h2",
8522
8735
  { class: "text-2xl font-bold text-gray-900" },
8523
8736
  "Two-Factor Authentication",
@@ -8527,7 +8740,7 @@ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
8527
8740
  vue.createElementVNode("button", {
8528
8741
  onClick: $setup.closeModal,
8529
8742
  class: "text-gray-400 hover:text-gray-600 transition-colors duration-200"
8530
- }, _cache[5] || (_cache[5] = [
8743
+ }, _cache[7] || (_cache[7] = [
8531
8744
  vue.createElementVNode(
8532
8745
  "svg",
8533
8746
  {
@@ -8553,7 +8766,7 @@ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
8553
8766
  default: vue.withCtx(() => [
8554
8767
  $setup.mfaLoading ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$6, [
8555
8768
  vue.createVNode($setup["StrandsUiLoader"], { size: 32 }),
8556
- _cache[7] || (_cache[7] = vue.createElementVNode(
8769
+ _cache[9] || (_cache[9] = vue.createElementVNode(
8557
8770
  "span",
8558
8771
  { class: "ml-3 text-gray-600" },
8559
8772
  "Loading MFA settings...",
@@ -8564,13 +8777,13 @@ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
8564
8777
  vue.Fragment,
8565
8778
  { key: 1 },
8566
8779
  [
8567
- vue.createCommentVNode(" Content when loaded "),
8780
+ vue.createCommentVNode(" Tab Navigation "),
8568
8781
  vue.createElementVNode("div", _hoisted_2$5, [
8569
8782
  vue.createCommentVNode(" MFA Status Overview "),
8570
8783
  vue.createElementVNode("div", _hoisted_3$5, [
8571
8784
  vue.createElementVNode("div", _hoisted_4$4, [
8572
8785
  vue.createElementVNode("div", null, [
8573
- _cache[8] || (_cache[8] = vue.createElementVNode(
8786
+ _cache[10] || (_cache[10] = vue.createElementVNode(
8574
8787
  "h3",
8575
8788
  { class: "font-semibold text-gray-900" },
8576
8789
  "Two-Factor Authentication",
@@ -8586,251 +8799,341 @@ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
8586
8799
  )
8587
8800
  ]),
8588
8801
  vue.createElementVNode("div", _hoisted_6$2, [
8589
- $setup.mfaEnabled ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_7$2, " ✓ Enabled ")) : (vue.openBlock(), vue.createElementBlock("span", _hoisted_8$2, " Not Enabled "))
8802
+ $setup.mfaEnabled ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_7$2, [
8803
+ vue.createVNode($setup["Shield"], {
8804
+ size: 12,
8805
+ class: "mr-1"
8806
+ }),
8807
+ _cache[11] || (_cache[11] = vue.createTextVNode(
8808
+ " Enabled ",
8809
+ -1
8810
+ /* CACHED */
8811
+ ))
8812
+ ])) : (vue.openBlock(), vue.createElementBlock("span", _hoisted_8$2, " Not Enabled "))
8590
8813
  ])
8591
8814
  ])
8592
8815
  ]),
8593
- vue.createCommentVNode(" Active Devices "),
8594
- $setup.activeMfaDevices.length > 0 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_9$2, [
8595
- _cache[12] || (_cache[12] = vue.createElementVNode(
8596
- "h3",
8597
- { class: "text-lg font-semibold text-gray-900 mb-4" },
8598
- "Active Devices",
8599
- -1
8600
- /* CACHED */
8601
- )),
8602
- vue.createElementVNode("div", _hoisted_10$2, [
8603
- (vue.openBlock(true), vue.createElementBlock(
8604
- vue.Fragment,
8605
- null,
8606
- vue.renderList($setup.activeMfaDevices, (device) => {
8607
- return vue.openBlock(), vue.createElementBlock("div", {
8608
- key: device.id,
8609
- class: "group flex items-center justify-between p-4 bg-white border border-gray-200 rounded-lg hover:border-gray-300 hover:shadow-md transition-all duration-200"
8610
- }, [
8611
- vue.createElementVNode("div", _hoisted_11$2, [
8612
- vue.createElementVNode(
8613
- "div",
8614
- {
8615
- class: vue.normalizeClass(["flex-shrink-0 w-10 h-10 rounded-lg flex items-center justify-center", $setup.getDeviceIconBackground(device.device_type)])
8616
- },
8617
- [
8618
- vue.createElementVNode(
8619
- "span",
8620
- _hoisted_12$2,
8621
- vue.toDisplayString($setup.getDeviceTypeIcon(device.device_type)),
8622
- 1
8623
- /* TEXT */
8624
- )
8625
- ],
8626
- 2
8627
- /* CLASS */
8628
- ),
8629
- vue.createElementVNode("div", _hoisted_13$2, [
8630
- vue.createElementVNode(
8631
- "h4",
8632
- _hoisted_14$2,
8633
- vue.toDisplayString(device.device_name),
8634
- 1
8635
- /* TEXT */
8636
- ),
8637
- vue.createElementVNode(
8638
- "p",
8639
- _hoisted_15$2,
8640
- vue.toDisplayString($setup.getDeviceTypeName(device.device_type)) + " • Last used " + vue.toDisplayString($setup.formatLastUsed(device.last_used_at)),
8641
- 1
8642
- /* TEXT */
8643
- )
8644
- ])
8816
+ vue.createCommentVNode(" Tab Navigation "),
8817
+ vue.createElementVNode("div", _hoisted_9$2, [
8818
+ vue.createElementVNode("nav", _hoisted_10$2, [
8819
+ vue.createElementVNode(
8820
+ "button",
8821
+ {
8822
+ onClick: _cache[0] || (_cache[0] = ($event) => $setup.activeTab = "add"),
8823
+ class: vue.normalizeClass([
8824
+ $setup.activeTab === "add" ? "border-[var(--strands-primary)] text-[var(--strands-primary)]" : "border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300",
8825
+ "whitespace-nowrap py-2 px-1 border-b-2 font-medium text-sm transition-colors"
8826
+ ])
8827
+ },
8828
+ " Add New Device ",
8829
+ 2
8830
+ /* CLASS */
8831
+ ),
8832
+ $setup.activeMfaDevices.length > 0 ? (vue.openBlock(), vue.createElementBlock(
8833
+ "button",
8834
+ {
8835
+ key: 0,
8836
+ onClick: _cache[1] || (_cache[1] = ($event) => $setup.activeTab = "manage"),
8837
+ class: vue.normalizeClass([
8838
+ $setup.activeTab === "manage" ? "border-[var(--strands-primary)] text-[var(--strands-primary)]" : "border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300",
8839
+ "whitespace-nowrap py-2 px-1 border-b-2 font-medium text-sm transition-colors"
8840
+ ])
8841
+ },
8842
+ " Active Devices (" + vue.toDisplayString($setup.activeMfaDevices.length) + ") ",
8843
+ 3
8844
+ /* TEXT, CLASS */
8845
+ )) : vue.createCommentVNode("v-if", true)
8846
+ ])
8847
+ ]),
8848
+ vue.createCommentVNode(" Tab Content: Add New Device "),
8849
+ $setup.activeTab === "add" ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_11$2, [
8850
+ vue.createElementVNode("div", null, [
8851
+ _cache[18] || (_cache[18] = vue.createElementVNode(
8852
+ "h3",
8853
+ { class: "text-xl font-semibold text-gray-900 mb-6" },
8854
+ "Choose Your Authentication Method",
8855
+ -1
8856
+ /* CACHED */
8857
+ )),
8858
+ vue.createElementVNode("div", _hoisted_12$2, [
8859
+ vue.createCommentVNode(" TOTP Setup "),
8860
+ vue.createElementVNode("div", {
8861
+ class: "group p-6 bg-white border border-gray-200 rounded-xl hover:border-gray-300 hover:shadow-md transition-all duration-200 cursor-pointer",
8862
+ onClick: $setup.startTotpSetup
8863
+ }, [
8864
+ vue.createElementVNode("div", _hoisted_13$2, [
8865
+ vue.createElementVNode("div", _hoisted_14$2, [
8866
+ vue.createVNode($setup["Smartphone"], {
8867
+ size: 24,
8868
+ class: "text-[var(--strands-primary)]"
8869
+ })
8645
8870
  ]),
8646
- vue.createElementVNode("div", _hoisted_16$2, [
8647
- vue.createCommentVNode(" Backup codes button for TOTP and Hardware Key devices "),
8648
- device.device_type === "totp" || device.device_type === "hardware" ? (vue.openBlock(), vue.createBlock($setup["StrandsUiButton"], {
8649
- key: 0,
8650
- variant: "secondary",
8651
- size: "sm",
8652
- onClick: ($event) => $setup.showBackupCodes(device),
8871
+ _cache[13] || (_cache[13] = vue.createElementVNode(
8872
+ "div",
8873
+ { class: "flex items-start space-x-4" },
8874
+ [
8875
+ vue.createElementVNode("div", { class: "min-w-0 flex-1" }, [
8876
+ vue.createElementVNode("h4", { class: "font-semibold text-gray-900 text-lg" }, "Authenticator App"),
8877
+ vue.createElementVNode("p", { class: "text-xs text-gray-500 mt-2" }, " Use Google Authenticator, Authy, or any TOTP-compatible app to generate secure codes ")
8878
+ ])
8879
+ ],
8880
+ -1
8881
+ /* CACHED */
8882
+ )),
8883
+ vue.createElementVNode("div", _hoisted_15$2, [
8884
+ vue.createVNode($setup["StrandsUiButton"], {
8885
+ variant: "primary",
8886
+ size: "md",
8887
+ onClick: vue.withModifiers($setup.startTotpSetup, ["stop"]),
8653
8888
  disabled: $setup.mfaLoading
8654
8889
  }, {
8655
- default: vue.withCtx(() => [..._cache[9] || (_cache[9] = [
8890
+ default: vue.withCtx(() => _cache[12] || (_cache[12] = [
8656
8891
  vue.createTextVNode(
8657
- " Backup Codes ",
8892
+ " Setup ",
8658
8893
  -1
8659
8894
  /* CACHED */
8660
8895
  )
8661
- ])]),
8662
- _: 2,
8663
- __: [9]
8664
- }, 1032, ["onClick", "disabled"])) : vue.createCommentVNode("v-if", true),
8665
- vue.createCommentVNode(" Test email MFA "),
8666
- device.device_type === "email" ? (vue.openBlock(), vue.createBlock($setup["StrandsUiButton"], {
8667
- key: 1,
8668
- variant: "secondary",
8669
- size: "sm",
8670
- onClick: ($event) => $setup.testEmailMfa(device),
8896
+ ])),
8897
+ _: 1,
8898
+ __: [12]
8899
+ }, 8, ["disabled"])
8900
+ ])
8901
+ ])
8902
+ ]),
8903
+ vue.createCommentVNode(" Email MFA Setup "),
8904
+ vue.createElementVNode("div", {
8905
+ class: "group p-6 bg-white border border-gray-200 rounded-xl hover:border-gray-300 hover:shadow-md transition-all duration-200 cursor-pointer",
8906
+ onClick: $setup.startEmailMfaSetup
8907
+ }, [
8908
+ vue.createElementVNode("div", _hoisted_16$2, [
8909
+ vue.createElementVNode("div", _hoisted_17$2, [
8910
+ vue.createVNode($setup["Mail"], {
8911
+ size: 24,
8912
+ class: "text-[var(--strands-primary)]"
8913
+ })
8914
+ ]),
8915
+ _cache[15] || (_cache[15] = vue.createElementVNode(
8916
+ "div",
8917
+ { class: "flex items-start space-x-4" },
8918
+ [
8919
+ vue.createElementVNode("div", { class: "min-w-0 flex-1" }, [
8920
+ vue.createElementVNode("h4", { class: "font-semibold text-gray-900 text-lg" }, "Email Verification"),
8921
+ vue.createElementVNode("p", { class: "text-xs text-gray-500 mt-2" }, " Receive verification codes directly in your email inbox for easy access ")
8922
+ ])
8923
+ ],
8924
+ -1
8925
+ /* CACHED */
8926
+ )),
8927
+ vue.createElementVNode("div", _hoisted_18$2, [
8928
+ vue.createVNode($setup["StrandsUiButton"], {
8929
+ variant: "primary",
8930
+ size: "md",
8931
+ onClick: vue.withModifiers($setup.startEmailMfaSetup, ["stop"]),
8671
8932
  disabled: $setup.mfaLoading
8672
8933
  }, {
8673
- default: vue.withCtx(() => [..._cache[10] || (_cache[10] = [
8934
+ default: vue.withCtx(() => _cache[14] || (_cache[14] = [
8674
8935
  vue.createTextVNode(
8675
- " Send Test Code ",
8936
+ " Setup ",
8676
8937
  -1
8677
8938
  /* CACHED */
8678
8939
  )
8679
- ])]),
8680
- _: 2,
8681
- __: [10]
8682
- }, 1032, ["onClick", "disabled"])) : vue.createCommentVNode("v-if", true),
8683
- vue.createCommentVNode(" Remove device "),
8940
+ ])),
8941
+ _: 1,
8942
+ __: [14]
8943
+ }, 8, ["disabled"])
8944
+ ])
8945
+ ])
8946
+ ]),
8947
+ vue.createCommentVNode(" Hardware Key & Passkeys Setup "),
8948
+ vue.createElementVNode("div", {
8949
+ class: "group p-6 bg-white border border-gray-200 rounded-xl hover:border-gray-300 hover:shadow-md transition-all duration-200 cursor-pointer",
8950
+ onClick: $setup.startHardwareKeySetup
8951
+ }, [
8952
+ vue.createElementVNode("div", _hoisted_19$2, [
8953
+ vue.createElementVNode("div", _hoisted_20$1, [
8954
+ vue.createVNode($setup["KeyRound"], {
8955
+ size: 24,
8956
+ class: "text-[var(--strands-primary)]"
8957
+ })
8958
+ ]),
8959
+ _cache[17] || (_cache[17] = vue.createElementVNode(
8960
+ "div",
8961
+ { class: "flex items-start space-x-4" },
8962
+ [
8963
+ vue.createElementVNode("div", { class: "min-w-0 flex-1" }, [
8964
+ vue.createElementVNode("h4", { class: "font-semibold text-gray-900 text-lg" }, "Hardware Key & Passkeys"),
8965
+ vue.createElementVNode("p", { class: "text-xs text-gray-500 mt-2" }, " Use YubiKey, FIDO2 devices, WebAuthn, or built-in passkeys for maximum security ")
8966
+ ])
8967
+ ],
8968
+ -1
8969
+ /* CACHED */
8970
+ )),
8971
+ vue.createElementVNode("div", _hoisted_21$1, [
8684
8972
  vue.createVNode($setup["StrandsUiButton"], {
8685
- variant: "secondary",
8686
- size: "sm",
8687
- onClick: ($event) => $setup.confirmDisableDevice(device),
8973
+ variant: "primary",
8974
+ size: "md",
8975
+ onClick: vue.withModifiers($setup.startHardwareKeySetup, ["stop"]),
8688
8976
  disabled: $setup.mfaLoading
8689
8977
  }, {
8690
- default: vue.withCtx(() => [..._cache[11] || (_cache[11] = [
8978
+ default: vue.withCtx(() => _cache[16] || (_cache[16] = [
8691
8979
  vue.createTextVNode(
8692
- " Remove ",
8980
+ " Setup ",
8693
8981
  -1
8694
8982
  /* CACHED */
8695
8983
  )
8696
- ])]),
8697
- _: 2,
8698
- __: [11]
8699
- }, 1032, ["onClick", "disabled"])
8984
+ ])),
8985
+ _: 1,
8986
+ __: [16]
8987
+ }, 8, ["disabled"])
8700
8988
  ])
8701
- ]);
8702
- }),
8703
- 128
8704
- /* KEYED_FRAGMENT */
8705
- ))
8989
+ ])
8990
+ ])
8991
+ ])
8706
8992
  ])
8707
- ])) : vue.createCommentVNode("v-if", true),
8708
- vue.createCommentVNode(" Add New Device "),
8709
- vue.createElementVNode("div", null, [
8710
- _cache[19] || (_cache[19] = vue.createElementVNode(
8711
- "h3",
8712
- { class: "text-lg font-semibold text-gray-900 mb-4" },
8713
- "Add New Device",
8714
- -1
8715
- /* CACHED */
8716
- )),
8717
- vue.createElementVNode("div", _hoisted_17$2, [
8718
- vue.createCommentVNode(" TOTP Setup "),
8719
- vue.createElementVNode("div", {
8720
- class: "group p-3 sm:p-4 border border-gray-200 rounded-lg hover:border-gray-300 hover:shadow-md transition-all duration-200 cursor-pointer active:scale-[0.98] touch-manipulation",
8721
- onClick: $setup.startTotpSetup
8722
- }, [
8723
- _cache[14] || (_cache[14] = vue.createElementVNode(
8724
- "div",
8725
- { class: "flex items-center space-x-3 mb-3" },
8726
- [
8727
- vue.createElementVNode("div", { class: "flex-shrink-0 w-10 h-10 bg-blue-50 rounded-lg flex items-center justify-center group-hover:bg-blue-100 transition-colors duration-200" }, [
8728
- vue.createElementVNode("span", { class: "text-xl" }, "📱")
8729
- ]),
8730
- vue.createElementVNode("div", { class: "min-w-0 flex-1" }, [
8731
- vue.createElementVNode("h4", { class: "font-medium text-gray-900 text-sm" }, "Authenticator App"),
8732
- vue.createElementVNode("p", { class: "text-xs text-gray-500 mt-0.5" }, "Google Authenticator, Authy, etc.")
8733
- ])
8734
- ],
8735
- -1
8736
- /* CACHED */
8737
- )),
8738
- vue.createVNode($setup["StrandsUiButton"], {
8739
- variant: "primary",
8740
- size: "sm",
8741
- onClick: vue.withModifiers($setup.startTotpSetup, ["stop"]),
8742
- disabled: $setup.mfaLoading,
8743
- class: "w-full"
8744
- }, {
8745
- default: vue.withCtx(() => _cache[13] || (_cache[13] = [
8746
- vue.createTextVNode(
8747
- " Setup TOTP ",
8748
- -1
8749
- /* CACHED */
8750
- )
8751
- ])),
8752
- _: 1,
8753
- __: [13]
8754
- }, 8, ["disabled"])
8755
- ]),
8756
- vue.createCommentVNode(" Email MFA Setup "),
8757
- vue.createElementVNode("div", {
8758
- class: "group p-3 sm:p-4 border border-gray-200 rounded-lg hover:border-gray-300 hover:shadow-md transition-all duration-200 cursor-pointer active:scale-[0.98] touch-manipulation",
8759
- onClick: $setup.startEmailMfaSetup
8760
- }, [
8761
- _cache[16] || (_cache[16] = vue.createElementVNode(
8762
- "div",
8763
- { class: "flex items-center space-x-3 mb-3" },
8764
- [
8765
- vue.createElementVNode("div", { class: "flex-shrink-0 w-10 h-10 bg-green-50 rounded-lg flex items-center justify-center group-hover:bg-green-100 transition-colors duration-200" }, [
8766
- vue.createElementVNode("span", { class: "text-xl" }, "📧")
8767
- ]),
8768
- vue.createElementVNode("div", { class: "min-w-0 flex-1" }, [
8769
- vue.createElementVNode("h4", { class: "font-medium text-gray-900 text-sm" }, "Email Verification"),
8770
- vue.createElementVNode("p", { class: "text-xs text-gray-500 mt-0.5" }, "Codes sent to your email")
8771
- ])
8772
- ],
8773
- -1
8774
- /* CACHED */
8775
- )),
8776
- vue.createVNode($setup["StrandsUiButton"], {
8777
- variant: "primary",
8778
- size: "sm",
8779
- onClick: vue.withModifiers($setup.startEmailMfaSetup, ["stop"]),
8780
- disabled: $setup.mfaLoading,
8781
- class: "w-full"
8782
- }, {
8783
- default: vue.withCtx(() => _cache[15] || (_cache[15] = [
8784
- vue.createTextVNode(
8785
- " Setup Email 2FA ",
8786
- -1
8787
- /* CACHED */
8788
- )
8789
- ])),
8790
- _: 1,
8791
- __: [15]
8792
- }, 8, ["disabled"])
8793
- ]),
8794
- vue.createCommentVNode(" Hardware Key & Passkeys Setup "),
8795
- vue.createElementVNode("div", {
8796
- class: "group p-3 sm:p-4 border border-gray-200 rounded-lg hover:border-gray-300 hover:shadow-md transition-all duration-200 cursor-pointer active:scale-[0.98] touch-manipulation sm:col-span-2 lg:col-span-1",
8797
- onClick: $setup.startHardwareKeySetup
8798
- }, [
8799
- _cache[18] || (_cache[18] = vue.createElementVNode(
8800
- "div",
8801
- { class: "flex items-center space-x-3 mb-3" },
8802
- [
8803
- vue.createElementVNode("div", { class: "flex-shrink-0 w-10 h-10 bg-purple-50 rounded-lg flex items-center justify-center group-hover:bg-purple-100 transition-colors duration-200" }, [
8804
- vue.createElementVNode("span", { class: "text-xl" }, "🔑")
8805
- ]),
8806
- vue.createElementVNode("div", { class: "min-w-0 flex-1" }, [
8807
- vue.createElementVNode("h4", { class: "font-medium text-gray-900 text-sm" }, "Hardware Key & Passkeys"),
8808
- vue.createElementVNode("p", { class: "text-xs text-gray-500 mt-0.5" }, "YubiKey, FIDO2, WebAuthn, Passkeys")
8809
- ])
8810
- ],
8811
- -1
8812
- /* CACHED */
8813
- )),
8814
- vue.createVNode($setup["StrandsUiButton"], {
8815
- variant: "primary",
8816
- size: "sm",
8817
- onClick: vue.withModifiers($setup.startHardwareKeySetup, ["stop"]),
8818
- disabled: $setup.mfaLoading,
8819
- class: "w-full"
8820
- }, {
8821
- default: vue.withCtx(() => _cache[17] || (_cache[17] = [
8822
- vue.createTextVNode(
8823
- " Setup Hardware Key ",
8824
- -1
8825
- /* CACHED */
8826
- )
8827
- ])),
8828
- _: 1,
8829
- __: [17]
8830
- }, 8, ["disabled"])
8993
+ ])) : $setup.activeTab === "manage" && $setup.activeMfaDevices.length > 0 ? (vue.openBlock(), vue.createElementBlock(
8994
+ vue.Fragment,
8995
+ { key: 1 },
8996
+ [
8997
+ vue.createCommentVNode(" Tab Content: Active Devices "),
8998
+ vue.createElementVNode("div", _hoisted_22$1, [
8999
+ vue.createElementVNode("div", null, [
9000
+ _cache[22] || (_cache[22] = vue.createElementVNode(
9001
+ "h3",
9002
+ { class: "text-xl font-semibold text-gray-900 mb-6" },
9003
+ "Manage Your Active Devices",
9004
+ -1
9005
+ /* CACHED */
9006
+ )),
9007
+ vue.createElementVNode("div", _hoisted_23$1, [
9008
+ (vue.openBlock(true), vue.createElementBlock(
9009
+ vue.Fragment,
9010
+ null,
9011
+ vue.renderList($setup.activeMfaDevices, (device) => {
9012
+ return vue.openBlock(), vue.createElementBlock("div", {
9013
+ key: device.id,
9014
+ class: "group p-6 bg-white border border-gray-200 rounded-xl hover:border-gray-300 hover:shadow-md transition-all duration-200"
9015
+ }, [
9016
+ vue.createElementVNode("div", _hoisted_24$1, [
9017
+ vue.createElementVNode("div", _hoisted_25$1, [
9018
+ vue.createElementVNode(
9019
+ "div",
9020
+ {
9021
+ class: vue.normalizeClass(["flex-shrink-0 w-14 h-14 rounded-xl flex items-center justify-center", $setup.getDeviceIconBackground(device.device_type)])
9022
+ },
9023
+ [
9024
+ (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent($setup.getDeviceIconComponent(device.device_type)), {
9025
+ size: 24,
9026
+ class: "text-gray-600"
9027
+ }))
9028
+ ],
9029
+ 2
9030
+ /* CLASS */
9031
+ ),
9032
+ vue.createElementVNode("div", _hoisted_26$1, [
9033
+ vue.createElementVNode(
9034
+ "h4",
9035
+ _hoisted_27$1,
9036
+ vue.toDisplayString(device.device_name),
9037
+ 1
9038
+ /* TEXT */
9039
+ ),
9040
+ vue.createElementVNode(
9041
+ "p",
9042
+ _hoisted_28$1,
9043
+ vue.toDisplayString($setup.getDeviceTypeName(device.device_type)),
9044
+ 1
9045
+ /* TEXT */
9046
+ ),
9047
+ vue.createElementVNode(
9048
+ "p",
9049
+ _hoisted_29$1,
9050
+ " Last used " + vue.toDisplayString($setup.formatLastUsed(device.last_used_at)),
9051
+ 1
9052
+ /* TEXT */
9053
+ )
9054
+ ])
9055
+ ]),
9056
+ vue.createElementVNode("div", _hoisted_30$1, [
9057
+ vue.createCommentVNode(" Backup codes button for TOTP and Hardware Key devices "),
9058
+ device.device_type === "totp" || device.device_type === "hardware" ? (vue.openBlock(), vue.createBlock($setup["StrandsUiButton"], {
9059
+ key: 0,
9060
+ variant: "secondary",
9061
+ size: "sm",
9062
+ onClick: ($event) => $setup.showBackupCodes(device),
9063
+ disabled: $setup.mfaLoading
9064
+ }, {
9065
+ default: vue.withCtx(() => [
9066
+ vue.createVNode($setup["KeyRound"], {
9067
+ size: 14,
9068
+ class: "mr-2"
9069
+ }),
9070
+ _cache[19] || (_cache[19] = vue.createTextVNode(
9071
+ " Backup Codes ",
9072
+ -1
9073
+ /* CACHED */
9074
+ ))
9075
+ ]),
9076
+ _: 2,
9077
+ __: [19]
9078
+ }, 1032, ["onClick", "disabled"])) : vue.createCommentVNode("v-if", true),
9079
+ vue.createCommentVNode(" Test email MFA "),
9080
+ device.device_type === "email" ? (vue.openBlock(), vue.createBlock($setup["StrandsUiButton"], {
9081
+ key: 1,
9082
+ variant: "secondary",
9083
+ size: "sm",
9084
+ onClick: ($event) => $setup.testEmailMfa(device),
9085
+ disabled: $setup.mfaLoading
9086
+ }, {
9087
+ default: vue.withCtx(() => [
9088
+ vue.createVNode($setup["Mail"], {
9089
+ size: 14,
9090
+ class: "mr-2"
9091
+ }),
9092
+ _cache[20] || (_cache[20] = vue.createTextVNode(
9093
+ " Send Test Code ",
9094
+ -1
9095
+ /* CACHED */
9096
+ ))
9097
+ ]),
9098
+ _: 2,
9099
+ __: [20]
9100
+ }, 1032, ["onClick", "disabled"])) : vue.createCommentVNode("v-if", true),
9101
+ vue.createCommentVNode(" Remove device "),
9102
+ vue.createVNode($setup["StrandsUiButton"], {
9103
+ variant: "secondary",
9104
+ size: "sm",
9105
+ onClick: ($event) => $setup.confirmDisableDevice(device),
9106
+ disabled: $setup.mfaLoading,
9107
+ class: "text-red-600 hover:bg-red-50 hover:text-red-700 border-red-200"
9108
+ }, {
9109
+ default: vue.withCtx(() => [
9110
+ vue.createVNode($setup["Trash2"], {
9111
+ size: 14,
9112
+ class: "mr-2"
9113
+ }),
9114
+ _cache[21] || (_cache[21] = vue.createTextVNode(
9115
+ " Remove ",
9116
+ -1
9117
+ /* CACHED */
9118
+ ))
9119
+ ]),
9120
+ _: 2,
9121
+ __: [21]
9122
+ }, 1032, ["onClick", "disabled"])
9123
+ ])
9124
+ ])
9125
+ ]);
9126
+ }),
9127
+ 128
9128
+ /* KEYED_FRAGMENT */
9129
+ ))
9130
+ ])
9131
+ ])
8831
9132
  ])
8832
- ])
8833
- ])
9133
+ ],
9134
+ 2112
9135
+ /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */
9136
+ )) : vue.createCommentVNode("v-if", true)
8834
9137
  ])
8835
9138
  ],
8836
9139
  2112
@@ -8839,26 +9142,26 @@ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
8839
9142
  $setup.showTotpSetup ? (vue.openBlock(), vue.createBlock($setup["StrandsTotpSetupModal"], {
8840
9143
  key: 2,
8841
9144
  show: $setup.showTotpSetup,
8842
- onClose: _cache[0] || (_cache[0] = ($event) => $setup.showTotpSetup = false),
9145
+ onClose: _cache[2] || (_cache[2] = ($event) => $setup.showTotpSetup = false),
8843
9146
  onSuccess: $setup.handleTotpSetupSuccess
8844
9147
  }, null, 8, ["show"])) : vue.createCommentVNode("v-if", true),
8845
9148
  $setup.showEmailMfaSetup ? (vue.openBlock(), vue.createBlock($setup["StrandsEmailMfaSetupModal"], {
8846
9149
  key: 3,
8847
9150
  show: $setup.showEmailMfaSetup,
8848
- onClose: _cache[1] || (_cache[1] = ($event) => $setup.showEmailMfaSetup = false),
9151
+ onClose: _cache[3] || (_cache[3] = ($event) => $setup.showEmailMfaSetup = false),
8849
9152
  onSuccess: $setup.handleEmailMfaSetupSuccess
8850
9153
  }, null, 8, ["show"])) : vue.createCommentVNode("v-if", true),
8851
9154
  $setup.showHardwareKeySetup ? (vue.openBlock(), vue.createBlock($setup["StrandsHardwareKeySetupModal"], {
8852
9155
  key: 4,
8853
9156
  show: $setup.showHardwareKeySetup,
8854
- onClose: _cache[2] || (_cache[2] = ($event) => $setup.showHardwareKeySetup = false),
9157
+ onClose: _cache[4] || (_cache[4] = ($event) => $setup.showHardwareKeySetup = false),
8855
9158
  onSuccess: $setup.handleHardwareKeySetupSuccess
8856
9159
  }, null, 8, ["show"])) : vue.createCommentVNode("v-if", true),
8857
9160
  $setup.showBackupCodesModal ? (vue.openBlock(), vue.createBlock($setup["StrandsBackupCodesModal"], {
8858
9161
  key: 5,
8859
9162
  show: $setup.showBackupCodesModal,
8860
9163
  device: $setup.selectedDevice,
8861
- onClose: _cache[3] || (_cache[3] = ($event) => $setup.showBackupCodesModal = false)
9164
+ onClose: _cache[5] || (_cache[5] = ($event) => $setup.showBackupCodesModal = false)
8862
9165
  }, null, 8, ["show", "device"])) : vue.createCommentVNode("v-if", true)
8863
9166
  ]),
8864
9167
  _: 1
@@ -8874,7 +9177,7 @@ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
8874
9177
  "cancel-text": "Keep Device",
8875
9178
  variant: "secondary",
8876
9179
  onConfirm: $setup.handleDisableDevice,
8877
- onCancel: _cache[4] || (_cache[4] = ($event) => $setup.showConfirmDisable = false)
9180
+ onCancel: _cache[6] || (_cache[6] = ($event) => $setup.showConfirmDisable = false)
8878
9181
  }, null, 8, ["show", "message"])) : vue.createCommentVNode("v-if", true)
8879
9182
  ],
8880
9183
  64
@@ -8896,6 +9199,7 @@ const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
8896
9199
  const emit = __emit;
8897
9200
  const { getSupportEmail, config: strandsConfig, getUrl } = useStrandsConfig.useStrandsConfig(props.config);
8898
9201
  const { fetchProfile, updateProfile, changeEmail, currentUser: authUser, currentSession, isAuthenticated, refreshToken, signOut } = useStrandsAuth.useStrandsAuth();
9202
+ const { mfaDevices: mfaDevices2, mfaEnabled: mfaEnabled2, activeMfaDevices, fetchMfaDevices } = useStrandsMfa();
8899
9203
  const internalUser = vue.ref(null);
8900
9204
  const fetchingProfile = vue.ref(false);
8901
9205
  const currentUser = vue.computed(() => {
@@ -8973,6 +9277,54 @@ const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
8973
9277
  const years = Math.floor(diffDays / 365);
8974
9278
  return years === 1 ? "1 year ago" : `${years} years ago`;
8975
9279
  });
9280
+ const deviceTypeCounts = vue.computed(() => {
9281
+ const devices = activeMfaDevices.value || [];
9282
+ const counts = {
9283
+ totp: 0,
9284
+ email: 0,
9285
+ hardware: 0,
9286
+ passkey: 0
9287
+ };
9288
+ devices.forEach((device) => {
9289
+ if (device.device_type in counts) {
9290
+ counts[device.device_type]++;
9291
+ }
9292
+ });
9293
+ return counts;
9294
+ });
9295
+ const mfaDeviceChips = vue.computed(() => {
9296
+ const chips = [];
9297
+ const counts = deviceTypeCounts.value;
9298
+ if (counts.totp > 0) {
9299
+ chips.push({
9300
+ type: "totp",
9301
+ count: counts.totp,
9302
+ label: counts.totp === 1 ? "Auth app" : "Auth apps",
9303
+ icon: Smartphone,
9304
+ color: "bg-blue-50 text-blue-700 border-blue-200"
9305
+ });
9306
+ }
9307
+ if (counts.email > 0) {
9308
+ chips.push({
9309
+ type: "email",
9310
+ count: counts.email,
9311
+ label: "Email",
9312
+ icon: Mail,
9313
+ color: "bg-green-50 text-green-700 border-green-200"
9314
+ });
9315
+ }
9316
+ if (counts.hardware > 0 || counts.passkey > 0) {
9317
+ const totalHardware = counts.hardware + counts.passkey;
9318
+ chips.push({
9319
+ type: "hardware",
9320
+ count: totalHardware,
9321
+ label: totalHardware === 1 ? "Key" : "Keys",
9322
+ icon: KeyRound,
9323
+ color: "bg-purple-50 text-purple-700 border-purple-200"
9324
+ });
9325
+ }
9326
+ return chips;
9327
+ });
8976
9328
  const getInitials2 = (firstName, lastName) => {
8977
9329
  if (!firstName && !lastName) return "U";
8978
9330
  return `${firstName?.[0] || ""}${lastName?.[0] || ""}`.toUpperCase();
@@ -8982,6 +9334,9 @@ const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
8982
9334
  fetchingProfile.value = true;
8983
9335
  try {
8984
9336
  await fetchProfile();
9337
+ if (isAuthenticated.value) {
9338
+ await fetchMfaDevices();
9339
+ }
8985
9340
  } catch (err) {
8986
9341
  const errorMsg = err instanceof Error ? err.message : "Failed to load profile";
8987
9342
  errorMessage.value = errorMsg;
@@ -9196,6 +9551,7 @@ const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
9196
9551
  const handleMfaUpdated = async () => {
9197
9552
  try {
9198
9553
  await fetchProfile();
9554
+ await fetchMfaDevices();
9199
9555
  successMessage.value = "MFA settings updated successfully";
9200
9556
  emit("mfa-toggle", currentUser.value?.mfaEnabled || false);
9201
9557
  } catch (err) {
@@ -9233,7 +9589,7 @@ const _sfc_main$7 = /* @__PURE__ */ vue.defineComponent({
9233
9589
  signingOut.value = false;
9234
9590
  }
9235
9591
  };
9236
- 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() {
9592
+ 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() {
9237
9593
  return StrandsUiButton;
9238
9594
  }, get StrandsUiInput() {
9239
9595
  return StrandsUiInput;
@@ -9279,38 +9635,44 @@ const _hoisted_16$1 = {
9279
9635
  };
9280
9636
  const _hoisted_17$1 = { class: "space-y-3 md:space-y-4" };
9281
9637
  const _hoisted_18$1 = { class: "space-y-4 p-4 bg-gray-50 rounded-xl" };
9282
- const _hoisted_19 = { class: "flex items-center justify-between gap-2" };
9638
+ const _hoisted_19$1 = { class: "flex items-center justify-between gap-2" };
9283
9639
  const _hoisted_20 = { class: "text-sm text-gray-600" };
9284
9640
  const _hoisted_21 = {
9285
9641
  key: 0,
9286
9642
  class: "space-y-3 overflow-hidden"
9287
9643
  };
9288
9644
  const _hoisted_22 = { class: "p-4 bg-gray-50 rounded-xl" };
9289
- const _hoisted_23 = { class: "flex items-center justify-between gap-2" };
9290
- const _hoisted_24 = { class: "text-sm text-gray-600" };
9291
- const _hoisted_25 = { class: "p-4 bg-gray-50 rounded-xl" };
9292
- const _hoisted_26 = { class: "flex items-center justify-between gap-2" };
9293
- const _hoisted_27 = { class: "text-sm text-gray-600" };
9294
- const _hoisted_28 = {
9645
+ const _hoisted_23 = { class: "flex items-start justify-between gap-4" };
9646
+ const _hoisted_24 = { class: "flex-1" };
9647
+ const _hoisted_25 = { class: "text-sm text-gray-600 mt-1" };
9648
+ const _hoisted_26 = {
9649
+ key: 0,
9650
+ class: "flex flex-wrap gap-2 mt-3"
9651
+ };
9652
+ const _hoisted_27 = { class: "ml-1" };
9653
+ const _hoisted_28 = { class: "p-4 bg-gray-50 rounded-xl" };
9654
+ const _hoisted_29 = { class: "flex items-center justify-between gap-2" };
9655
+ const _hoisted_30 = { class: "text-sm text-gray-600" };
9656
+ const _hoisted_31 = {
9295
9657
  key: 0,
9296
9658
  class: "flex flex-col sm:flex-row gap-3 pt-6 border-t border-gray-200 animate-slide-up"
9297
9659
  };
9298
- const _hoisted_29 = {
9660
+ const _hoisted_32 = {
9299
9661
  key: 0,
9300
9662
  class: "mt-6 animate-fade-in"
9301
9663
  };
9302
- const _hoisted_30 = { class: "alert-success" };
9303
- const _hoisted_31 = { class: "flex items-start gap-3" };
9304
- const _hoisted_32 = { class: "font-medium" };
9305
- const _hoisted_33 = {
9664
+ const _hoisted_33 = { class: "alert-success" };
9665
+ const _hoisted_34 = { class: "flex items-start gap-3" };
9666
+ const _hoisted_35 = { class: "font-medium" };
9667
+ const _hoisted_36 = {
9306
9668
  key: 1,
9307
9669
  class: "mt-6 animate-fade-in"
9308
9670
  };
9309
- const _hoisted_34 = { class: "alert-error" };
9310
- const _hoisted_35 = { class: "flex items-start gap-3" };
9311
- const _hoisted_36 = { class: "font-medium" };
9312
- const _hoisted_37 = { key: 0 };
9313
- const _hoisted_38 = { class: "text-gray-400 text-sm" };
9671
+ const _hoisted_37 = { class: "alert-error" };
9672
+ const _hoisted_38 = { class: "flex items-start gap-3" };
9673
+ const _hoisted_39 = { class: "font-medium" };
9674
+ const _hoisted_40 = { key: 0 };
9675
+ const _hoisted_41 = { class: "text-gray-400 text-sm" };
9314
9676
  function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
9315
9677
  return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$5, [
9316
9678
  vue.createElementVNode("div", _hoisted_2$4, [
@@ -9525,7 +9887,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
9525
9887
  )),
9526
9888
  vue.createCommentVNode(" Password Change "),
9527
9889
  vue.createElementVNode("div", _hoisted_18$1, [
9528
- vue.createElementVNode("div", _hoisted_19, [
9890
+ vue.createElementVNode("div", _hoisted_19$1, [
9529
9891
  vue.createElementVNode("div", null, [
9530
9892
  _cache[15] || (_cache[15] = vue.createElementVNode(
9531
9893
  "h4",
@@ -9607,7 +9969,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
9607
9969
  vue.createCommentVNode(" Two-Factor Authentication "),
9608
9970
  vue.createElementVNode("div", _hoisted_22, [
9609
9971
  vue.createElementVNode("div", _hoisted_23, [
9610
- vue.createElementVNode("div", null, [
9972
+ vue.createElementVNode("div", _hoisted_24, [
9611
9973
  _cache[17] || (_cache[17] = vue.createElementVNode(
9612
9974
  "h4",
9613
9975
  { class: "font-medium text-gray-900" },
@@ -9617,16 +9979,60 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
9617
9979
  )),
9618
9980
  vue.createElementVNode(
9619
9981
  "p",
9620
- _hoisted_24,
9982
+ _hoisted_25,
9621
9983
  vue.toDisplayString($setup.currentUser?.mfaEnabled ? "Enabled" : "Add extra security to your account"),
9622
9984
  1
9623
9985
  /* TEXT */
9624
- )
9986
+ ),
9987
+ vue.createCommentVNode(" Device Type Chips "),
9988
+ $setup.mfaDeviceChips.length > 0 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_26, [
9989
+ (vue.openBlock(true), vue.createElementBlock(
9990
+ vue.Fragment,
9991
+ null,
9992
+ vue.renderList($setup.mfaDeviceChips, (chip) => {
9993
+ return vue.openBlock(), vue.createElementBlock(
9994
+ "div",
9995
+ {
9996
+ key: chip.type,
9997
+ class: vue.normalizeClass([
9998
+ "inline-flex items-center px-2.5 py-1 rounded-lg text-xs font-medium border transition-colors",
9999
+ chip.color
10000
+ ])
10001
+ },
10002
+ [
10003
+ (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(chip.icon), {
10004
+ size: 12,
10005
+ class: "mr-1.5"
10006
+ })),
10007
+ vue.createElementVNode(
10008
+ "span",
10009
+ null,
10010
+ vue.toDisplayString(chip.count),
10011
+ 1
10012
+ /* TEXT */
10013
+ ),
10014
+ vue.createElementVNode(
10015
+ "span",
10016
+ _hoisted_27,
10017
+ vue.toDisplayString(chip.label),
10018
+ 1
10019
+ /* TEXT */
10020
+ )
10021
+ ],
10022
+ 2
10023
+ /* CLASS */
10024
+ );
10025
+ }),
10026
+ 128
10027
+ /* KEYED_FRAGMENT */
10028
+ ))
10029
+ ])) : vue.createCommentVNode("v-if", true)
9625
10030
  ]),
9626
10031
  vue.createVNode($setup["StrandsUiButton"], {
9627
10032
  variant: $setup.currentUser?.mfaEnabled ? "secondary" : "primary",
9628
10033
  size: "sm",
9629
- onClick: _cache[9] || (_cache[9] = ($event) => $setup.showMfaModal = true)
10034
+ onClick: _cache[9] || (_cache[9] = ($event) => $setup.showMfaModal = true),
10035
+ class: "flex-shrink-0"
9630
10036
  }, {
9631
10037
  default: vue.withCtx(() => [
9632
10038
  vue.createTextVNode(
@@ -9641,8 +10047,8 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
9641
10047
  ])
9642
10048
  ]),
9643
10049
  vue.createCommentVNode(" Active Sessions "),
9644
- vue.createElementVNode("div", _hoisted_25, [
9645
- vue.createElementVNode("div", _hoisted_26, [
10050
+ vue.createElementVNode("div", _hoisted_28, [
10051
+ vue.createElementVNode("div", _hoisted_29, [
9646
10052
  vue.createElementVNode("div", null, [
9647
10053
  _cache[18] || (_cache[18] = vue.createElementVNode(
9648
10054
  "h4",
@@ -9653,7 +10059,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
9653
10059
  )),
9654
10060
  vue.createElementVNode(
9655
10061
  "p",
9656
- _hoisted_27,
10062
+ _hoisted_30,
9657
10063
  vue.toDisplayString($setup.activeSessions.length) + " active device(s)",
9658
10064
  1
9659
10065
  /* TEXT */
@@ -9680,7 +10086,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
9680
10086
  ])
9681
10087
  ]),
9682
10088
  vue.createCommentVNode(" Action Buttons - Only show when changes are made "),
9683
- $setup.hasChanges ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_28, [
10089
+ $setup.hasChanges ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_31, [
9684
10090
  vue.createVNode($setup["StrandsUiButton"], {
9685
10091
  type: "submit",
9686
10092
  variant: "primary",
@@ -9718,9 +10124,9 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
9718
10124
  /* NEED_HYDRATION */
9719
10125
  ),
9720
10126
  vue.createCommentVNode(" Success/Error Messages "),
9721
- $setup.successMessage ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_29, [
9722
- vue.createElementVNode("div", _hoisted_30, [
9723
- vue.createElementVNode("div", _hoisted_31, [
10127
+ $setup.successMessage ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_32, [
10128
+ vue.createElementVNode("div", _hoisted_33, [
10129
+ vue.createElementVNode("div", _hoisted_34, [
9724
10130
  _cache[22] || (_cache[22] = vue.createElementVNode(
9725
10131
  "svg",
9726
10132
  {
@@ -9740,7 +10146,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
9740
10146
  )),
9741
10147
  vue.createElementVNode(
9742
10148
  "p",
9743
- _hoisted_32,
10149
+ _hoisted_35,
9744
10150
  vue.toDisplayString($setup.successMessage),
9745
10151
  1
9746
10152
  /* TEXT */
@@ -9748,9 +10154,9 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
9748
10154
  ])
9749
10155
  ])
9750
10156
  ])) : vue.createCommentVNode("v-if", true),
9751
- $setup.errorMessage ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_33, [
9752
- vue.createElementVNode("div", _hoisted_34, [
9753
- vue.createElementVNode("div", _hoisted_35, [
10157
+ $setup.errorMessage ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_36, [
10158
+ vue.createElementVNode("div", _hoisted_37, [
10159
+ vue.createElementVNode("div", _hoisted_38, [
9754
10160
  _cache[23] || (_cache[23] = vue.createElementVNode(
9755
10161
  "svg",
9756
10162
  {
@@ -9770,7 +10176,7 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
9770
10176
  )),
9771
10177
  vue.createElementVNode(
9772
10178
  "p",
9773
- _hoisted_36,
10179
+ _hoisted_39,
9774
10180
  vue.toDisplayString($setup.errorMessage),
9775
10181
  1
9776
10182
  /* TEXT */
@@ -9801,8 +10207,8 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
9801
10207
  /* STABLE */
9802
10208
  }, 8, ["disabled"]),
9803
10209
  vue.createCommentVNode(" Need help "),
9804
- $setup.getSupportEmail() ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_37, [
9805
- vue.createElementVNode("p", _hoisted_38, [
10210
+ $setup.getSupportEmail() ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_40, [
10211
+ vue.createElementVNode("p", _hoisted_41, [
9806
10212
  _cache[25] || (_cache[25] = vue.createTextVNode(
9807
10213
  " Need help? ",
9808
10214
  -1
@@ -10041,129 +10447,6 @@ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
10041
10447
  ]);
10042
10448
  }
10043
10449
  const StrandsPasswordReset = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["render", _sfc_render$6], ["__file", "/home/runner/work/strands-accounts/strands-accounts/apps/accounts-ui/src/vue/components/StrandsPasswordReset.vue"]]);
10044
- /**
10045
- * @license lucide-vue-next v0.539.0 - ISC
10046
- *
10047
- * This source code is licensed under the ISC license.
10048
- * See the LICENSE file in the root directory of this source tree.
10049
- */
10050
- const toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
10051
- const toCamelCase = (string) => string.replace(
10052
- /^([A-Z])|[\s-_]+(\w)/g,
10053
- (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()
10054
- );
10055
- const toPascalCase = (string) => {
10056
- const camelCase = toCamelCase(string);
10057
- return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);
10058
- };
10059
- const mergeClasses = (...classes) => classes.filter((className, index, array) => {
10060
- return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index;
10061
- }).join(" ").trim();
10062
- const isEmptyString = (value) => value === "";
10063
- /**
10064
- * @license lucide-vue-next v0.539.0 - ISC
10065
- *
10066
- * This source code is licensed under the ISC license.
10067
- * See the LICENSE file in the root directory of this source tree.
10068
- */
10069
- var defaultAttributes = {
10070
- xmlns: "http://www.w3.org/2000/svg",
10071
- width: 24,
10072
- height: 24,
10073
- viewBox: "0 0 24 24",
10074
- fill: "none",
10075
- stroke: "currentColor",
10076
- "stroke-width": 2,
10077
- "stroke-linecap": "round",
10078
- "stroke-linejoin": "round"
10079
- };
10080
- /**
10081
- * @license lucide-vue-next v0.539.0 - ISC
10082
- *
10083
- * This source code is licensed under the ISC license.
10084
- * See the LICENSE file in the root directory of this source tree.
10085
- */
10086
- const Icon = ({
10087
- name,
10088
- iconNode,
10089
- absoluteStrokeWidth,
10090
- "absolute-stroke-width": absoluteStrokeWidthKebabCase,
10091
- strokeWidth,
10092
- "stroke-width": strokeWidthKebabCase,
10093
- size = defaultAttributes.width,
10094
- color = defaultAttributes.stroke,
10095
- ...props
10096
- }, { slots }) => {
10097
- return vue.h(
10098
- "svg",
10099
- {
10100
- ...defaultAttributes,
10101
- ...props,
10102
- width: size,
10103
- height: size,
10104
- stroke: color,
10105
- "stroke-width": isEmptyString(absoluteStrokeWidth) || isEmptyString(absoluteStrokeWidthKebabCase) || absoluteStrokeWidth === true || absoluteStrokeWidthKebabCase === true ? Number(strokeWidth || strokeWidthKebabCase || defaultAttributes["stroke-width"]) * 24 / Number(size) : strokeWidth || strokeWidthKebabCase || defaultAttributes["stroke-width"],
10106
- class: mergeClasses(
10107
- "lucide",
10108
- props.class,
10109
- ...name ? [`lucide-${toKebabCase(toPascalCase(name))}-icon`, `lucide-${toKebabCase(name)}`] : ["lucide-icon"]
10110
- )
10111
- },
10112
- [...iconNode.map((child) => vue.h(...child)), ...slots.default ? [slots.default()] : []]
10113
- );
10114
- };
10115
- /**
10116
- * @license lucide-vue-next v0.539.0 - ISC
10117
- *
10118
- * This source code is licensed under the ISC license.
10119
- * See the LICENSE file in the root directory of this source tree.
10120
- */
10121
- const createLucideIcon = (iconName, iconNode) => (props, { slots, attrs }) => vue.h(
10122
- Icon,
10123
- {
10124
- ...attrs,
10125
- ...props,
10126
- iconNode,
10127
- name: iconName
10128
- },
10129
- slots
10130
- );
10131
- /**
10132
- * @license lucide-vue-next v0.539.0 - ISC
10133
- *
10134
- * This source code is licensed under the ISC license.
10135
- * See the LICENSE file in the root directory of this source tree.
10136
- */
10137
- const KeyRound = createLucideIcon("key-round", [
10138
- [
10139
- "path",
10140
- {
10141
- d: "M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z",
10142
- key: "1s6t7t"
10143
- }
10144
- ],
10145
- ["circle", { cx: "16.5", cy: "7.5", r: ".5", fill: "currentColor", key: "w0ekpg" }]
10146
- ]);
10147
- /**
10148
- * @license lucide-vue-next v0.539.0 - ISC
10149
- *
10150
- * This source code is licensed under the ISC license.
10151
- * See the LICENSE file in the root directory of this source tree.
10152
- */
10153
- const Mail = createLucideIcon("mail", [
10154
- ["path", { d: "m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7", key: "132q7q" }],
10155
- ["rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", key: "izxlao" }]
10156
- ]);
10157
- /**
10158
- * @license lucide-vue-next v0.539.0 - ISC
10159
- *
10160
- * This source code is licensed under the ISC license.
10161
- * See the LICENSE file in the root directory of this source tree.
10162
- */
10163
- const Smartphone = createLucideIcon("smartphone", [
10164
- ["rect", { width: "14", height: "20", x: "5", y: "2", rx: "2", ry: "2", key: "1yt0o3" }],
10165
- ["path", { d: "M12 18h.01", key: "mhygvu" }]
10166
- ]);
10167
10450
  const _sfc_main$5 = /* @__PURE__ */ vue.defineComponent({
10168
10451
  __name: "StrandsMFASetup",
10169
10452
  props: {
@@ -10230,6 +10513,10 @@ const _sfc_main$5 = /* @__PURE__ */ vue.defineComponent({
10230
10513
  return Mail;
10231
10514
  }, get KeyRound() {
10232
10515
  return KeyRound;
10516
+ }, get Shield() {
10517
+ return Shield;
10518
+ }, get Settings() {
10519
+ return Settings;
10233
10520
  } };
10234
10521
  Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
10235
10522
  return __returned__;
@@ -10237,28 +10524,32 @@ const _sfc_main$5 = /* @__PURE__ */ vue.defineComponent({
10237
10524
  });
10238
10525
  const _hoisted_1$3 = { class: "flex items-center justify-between" };
10239
10526
  const _hoisted_2$2 = { class: "text-right" };
10240
- const _hoisted_3$2 = { class: "space-y-6" };
10527
+ const _hoisted_3$2 = { class: "space-y-8" };
10241
10528
  const _hoisted_4$1 = {
10242
10529
  key: 0,
10243
- class: "flex items-center justify-center py-12"
10530
+ class: "flex items-center justify-center py-16"
10244
10531
  };
10245
- const _hoisted_5$1 = { class: "space-y-6" };
10532
+ const _hoisted_5$1 = { class: "space-y-8" };
10246
10533
  const _hoisted_6 = {
10247
10534
  key: 0,
10248
- class: "bg-green-50 border border-green-200 rounded-lg p-4"
10535
+ class: "bg-green-50 border border-green-200 rounded-xl p-6"
10249
10536
  };
10250
- const _hoisted_7 = { class: "grid grid-cols-1 md:grid-cols-3 gap-4" };
10251
- const _hoisted_8 = { class: "p-6 border border-gray-200 rounded-lg hover:shadow-sm hover:border-[var(--strands-primary)] transition-all duration-200" };
10252
- const _hoisted_9 = { class: "flex flex-col items-center text-center space-y-3" };
10253
- const _hoisted_10 = { class: "w-12 h-12 bg-[var(--strands-primary)] bg-opacity-10 rounded-lg flex items-center justify-center" };
10254
- const _hoisted_11 = { class: "p-6 border border-gray-200 rounded-lg hover:shadow-sm hover:border-[var(--strands-primary)] transition-all duration-200" };
10255
- const _hoisted_12 = { class: "flex flex-col items-center text-center space-y-3" };
10256
- const _hoisted_13 = { class: "w-12 h-12 bg-[var(--strands-primary)] bg-opacity-10 rounded-lg flex items-center justify-center" };
10257
- const _hoisted_14 = { class: "p-6 border border-gray-200 rounded-lg hover:shadow-sm hover:border-[var(--strands-primary)] transition-all duration-200" };
10258
- const _hoisted_15 = { class: "flex flex-col items-center text-center space-y-3" };
10259
- const _hoisted_16 = { class: "w-12 h-12 bg-[var(--strands-primary)] bg-opacity-10 rounded-lg flex items-center justify-center" };
10260
- const _hoisted_17 = { key: 1 };
10261
- const _hoisted_18 = { class: "flex justify-end space-x-3" };
10537
+ const _hoisted_7 = { class: "flex items-center space-x-3" };
10538
+ const _hoisted_8 = { class: "w-10 h-10 bg-green-100 rounded-full flex items-center justify-center" };
10539
+ const _hoisted_9 = { class: "grid grid-cols-1 md:grid-cols-3 gap-6" };
10540
+ const _hoisted_10 = { class: "flex flex-col items-center text-center space-y-4" };
10541
+ const _hoisted_11 = { class: "w-16 h-16 bg-[var(--strands-primary)] bg-opacity-10 rounded-xl flex items-center justify-center group-hover:bg-[var(--strands-primary)] group-hover:bg-opacity-15 transition-colors" };
10542
+ const _hoisted_12 = { class: "flex flex-col items-center text-center space-y-4" };
10543
+ const _hoisted_13 = { class: "w-16 h-16 bg-[var(--strands-primary)] bg-opacity-10 rounded-xl flex items-center justify-center group-hover:bg-[var(--strands-primary)] group-hover:bg-opacity-15 transition-colors" };
10544
+ const _hoisted_14 = { class: "flex flex-col items-center text-center space-y-4" };
10545
+ const _hoisted_15 = { class: "w-16 h-16 bg-[var(--strands-primary)] bg-opacity-10 rounded-xl flex items-center justify-center group-hover:bg-[var(--strands-primary)] group-hover:bg-opacity-15 transition-colors" };
10546
+ const _hoisted_16 = {
10547
+ key: 1,
10548
+ class: "border-t border-gray-200 pt-8"
10549
+ };
10550
+ const _hoisted_17 = { class: "flex items-center justify-between" };
10551
+ const _hoisted_18 = { class: "text-gray-600 text-sm mt-1" };
10552
+ const _hoisted_19 = { class: "flex justify-end space-x-3" };
10262
10553
  function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
10263
10554
  return vue.openBlock(), vue.createElementBlock(
10264
10555
  vue.Fragment,
@@ -10267,7 +10558,7 @@ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
10267
10558
  vue.createVNode($setup["UiModal"], {
10268
10559
  open: $props.show,
10269
10560
  onClose: $setup.closeModal,
10270
- "card-class": "max-w-4xl"
10561
+ "card-class": "max-w-5xl"
10271
10562
  }, {
10272
10563
  header: vue.withCtx(() => [
10273
10564
  vue.createElementVNode("div", _hoisted_1$3, [
@@ -10295,7 +10586,7 @@ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
10295
10586
  ])
10296
10587
  ]),
10297
10588
  footer: vue.withCtx(() => [
10298
- vue.createElementVNode("div", _hoisted_18, [
10589
+ vue.createElementVNode("div", _hoisted_19, [
10299
10590
  vue.createVNode($setup["StrandsUiButton"], {
10300
10591
  variant: "secondary",
10301
10592
  onClick: $setup.closeModal,
@@ -10332,67 +10623,68 @@ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
10332
10623
  vue.createCommentVNode(" MFA Options "),
10333
10624
  vue.createElementVNode("div", _hoisted_5$1, [
10334
10625
  vue.createCommentVNode(" Current MFA Status "),
10335
- $setup.mfaEnabled || $setup.activeMfaDevices.length > 0 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_6, _cache[6] || (_cache[6] = [
10336
- vue.createElementVNode(
10337
- "div",
10338
- { class: "flex items-center space-x-2" },
10339
- [
10340
- vue.createElementVNode("svg", {
10341
- class: "w-5 h-5 text-green-600",
10342
- fill: "currentColor",
10343
- viewBox: "0 0 20 20"
10344
- }, [
10345
- vue.createElementVNode("path", {
10346
- "fill-rule": "evenodd",
10347
- d: "M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z",
10348
- "clip-rule": "evenodd"
10349
- })
10350
- ]),
10351
- vue.createElementVNode("span", { class: "text-green-800 font-medium" }, "2FA is currently enabled on your account")
10352
- ],
10353
- -1
10354
- /* CACHED */
10355
- )
10356
- ]))) : vue.createCommentVNode("v-if", true),
10626
+ $setup.mfaEnabled || $setup.activeMfaDevices.length > 0 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_6, [
10627
+ vue.createElementVNode("div", _hoisted_7, [
10628
+ vue.createElementVNode("div", _hoisted_8, [
10629
+ vue.createVNode($setup["Shield"], {
10630
+ size: 20,
10631
+ class: "text-green-600"
10632
+ })
10633
+ ]),
10634
+ _cache[6] || (_cache[6] = vue.createElementVNode(
10635
+ "div",
10636
+ null,
10637
+ [
10638
+ vue.createElementVNode("span", { class: "text-green-800 font-medium text-lg" }, "2FA is currently enabled on your account"),
10639
+ vue.createElementVNode("p", { class: "text-green-700 text-sm mt-1" }, "Your account has additional security protection")
10640
+ ],
10641
+ -1
10642
+ /* CACHED */
10643
+ ))
10644
+ ])
10645
+ ])) : vue.createCommentVNode("v-if", true),
10357
10646
  vue.createCommentVNode(" Setup Options "),
10358
10647
  vue.createElementVNode("div", null, [
10359
10648
  _cache[13] || (_cache[13] = vue.createElementVNode(
10360
10649
  "h3",
10361
- { class: "text-lg font-semibold text-gray-900 mb-4" },
10362
- "Add New Device",
10650
+ { class: "text-xl font-semibold text-gray-900 mb-6" },
10651
+ "Choose Your Authentication Method",
10363
10652
  -1
10364
10653
  /* CACHED */
10365
10654
  )),
10366
- vue.createElementVNode("div", _hoisted_7, [
10655
+ vue.createElementVNode("div", _hoisted_9, [
10367
10656
  vue.createCommentVNode(" TOTP Setup "),
10368
- vue.createElementVNode("div", _hoisted_8, [
10369
- vue.createElementVNode("div", _hoisted_9, [
10370
- vue.createElementVNode("div", _hoisted_10, [
10657
+ vue.createElementVNode("div", {
10658
+ class: "group p-8 border border-gray-200 rounded-xl hover:shadow-lg hover:border-[var(--strands-primary)] transition-all duration-200 cursor-pointer",
10659
+ onClick: $setup.startTotpSetup
10660
+ }, [
10661
+ vue.createElementVNode("div", _hoisted_10, [
10662
+ vue.createElementVNode("div", _hoisted_11, [
10371
10663
  vue.createVNode($setup["Smartphone"], {
10372
- size: 24,
10664
+ size: 28,
10373
10665
  class: "text-[var(--strands-primary)]"
10374
10666
  })
10375
10667
  ]),
10376
10668
  _cache[8] || (_cache[8] = vue.createElementVNode(
10377
10669
  "div",
10378
- null,
10670
+ { class: "space-y-2" },
10379
10671
  [
10380
- vue.createElementVNode("h4", { class: "font-medium text-gray-900" }, "Authenticator App"),
10381
- vue.createElementVNode("p", { class: "text-sm text-gray-500" }, "Google Authenticator, Authy, etc.")
10672
+ vue.createElementVNode("h4", { class: "font-semibold text-gray-900 text-lg" }, "Authenticator App"),
10673
+ vue.createElementVNode("p", { class: "text-sm text-gray-500 leading-relaxed" }, "Use Google Authenticator, Authy, or any TOTP-compatible app to generate secure codes")
10382
10674
  ],
10383
10675
  -1
10384
10676
  /* CACHED */
10385
10677
  )),
10386
10678
  vue.createVNode($setup["StrandsUiButton"], {
10387
10679
  variant: "primary",
10388
- size: "sm",
10389
- onClick: $setup.startTotpSetup,
10680
+ size: "md",
10681
+ onClick: vue.withModifiers($setup.startTotpSetup, ["stop"]),
10390
10682
  disabled: $setup.loading,
10391
- class: "w-full"
10683
+ class: "w-full mt-4"
10392
10684
  }, {
10393
10685
  default: vue.withCtx(() => _cache[7] || (_cache[7] = [
10394
10686
  vue.createTextVNode(
10395
- " Setup TOTP ",
10687
+ " Setup Authenticator ",
10396
10688
  -1
10397
10689
  /* CACHED */
10398
10690
  )
@@ -10403,30 +10695,33 @@ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
10403
10695
  ])
10404
10696
  ]),
10405
10697
  vue.createCommentVNode(" Email MFA Setup "),
10406
- vue.createElementVNode("div", _hoisted_11, [
10698
+ vue.createElementVNode("div", {
10699
+ class: "group p-8 border border-gray-200 rounded-xl hover:shadow-lg hover:border-[var(--strands-primary)] transition-all duration-200 cursor-pointer",
10700
+ onClick: $setup.startEmailMfaSetup
10701
+ }, [
10407
10702
  vue.createElementVNode("div", _hoisted_12, [
10408
10703
  vue.createElementVNode("div", _hoisted_13, [
10409
10704
  vue.createVNode($setup["Mail"], {
10410
- size: 24,
10705
+ size: 28,
10411
10706
  class: "text-[var(--strands-primary)]"
10412
10707
  })
10413
10708
  ]),
10414
10709
  _cache[10] || (_cache[10] = vue.createElementVNode(
10415
10710
  "div",
10416
- null,
10711
+ { class: "space-y-2" },
10417
10712
  [
10418
- vue.createElementVNode("h4", { class: "font-medium text-gray-900" }, "Email Verification"),
10419
- vue.createElementVNode("p", { class: "text-sm text-gray-500" }, "Codes sent to your email")
10713
+ vue.createElementVNode("h4", { class: "font-semibold text-gray-900 text-lg" }, "Email Verification"),
10714
+ vue.createElementVNode("p", { class: "text-sm text-gray-500 leading-relaxed" }, "Receive verification codes directly in your email inbox for easy access")
10420
10715
  ],
10421
10716
  -1
10422
10717
  /* CACHED */
10423
10718
  )),
10424
10719
  vue.createVNode($setup["StrandsUiButton"], {
10425
10720
  variant: "primary",
10426
- size: "sm",
10427
- onClick: $setup.startEmailMfaSetup,
10721
+ size: "md",
10722
+ onClick: vue.withModifiers($setup.startEmailMfaSetup, ["stop"]),
10428
10723
  disabled: $setup.loading,
10429
- class: "w-full"
10724
+ class: "w-full mt-4"
10430
10725
  }, {
10431
10726
  default: vue.withCtx(() => _cache[9] || (_cache[9] = [
10432
10727
  vue.createTextVNode(
@@ -10441,30 +10736,33 @@ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
10441
10736
  ])
10442
10737
  ]),
10443
10738
  vue.createCommentVNode(" Hardware Key Setup "),
10444
- vue.createElementVNode("div", _hoisted_14, [
10445
- vue.createElementVNode("div", _hoisted_15, [
10446
- vue.createElementVNode("div", _hoisted_16, [
10739
+ vue.createElementVNode("div", {
10740
+ class: "group p-8 border border-gray-200 rounded-xl hover:shadow-lg hover:border-[var(--strands-primary)] transition-all duration-200 cursor-pointer",
10741
+ onClick: $setup.startHardwareKeySetup
10742
+ }, [
10743
+ vue.createElementVNode("div", _hoisted_14, [
10744
+ vue.createElementVNode("div", _hoisted_15, [
10447
10745
  vue.createVNode($setup["KeyRound"], {
10448
- size: 24,
10746
+ size: 28,
10449
10747
  class: "text-[var(--strands-primary)]"
10450
10748
  })
10451
10749
  ]),
10452
10750
  _cache[12] || (_cache[12] = vue.createElementVNode(
10453
10751
  "div",
10454
- null,
10752
+ { class: "space-y-2" },
10455
10753
  [
10456
- vue.createElementVNode("h4", { class: "font-medium text-gray-900" }, "Hardware Key & Passkeys"),
10457
- vue.createElementVNode("p", { class: "text-sm text-gray-500" }, "YubiKey, FIDO2, WebAuthn, Passkeys")
10754
+ vue.createElementVNode("h4", { class: "font-semibold text-gray-900 text-lg" }, "Hardware Key & Passkeys"),
10755
+ vue.createElementVNode("p", { class: "text-sm text-gray-500 leading-relaxed" }, "Use YubiKey, FIDO2 devices, WebAuthn, or built-in passkeys for maximum security")
10458
10756
  ],
10459
10757
  -1
10460
10758
  /* CACHED */
10461
10759
  )),
10462
10760
  vue.createVNode($setup["StrandsUiButton"], {
10463
10761
  variant: "primary",
10464
- size: "sm",
10465
- onClick: $setup.startHardwareKeySetup,
10762
+ size: "md",
10763
+ onClick: vue.withModifiers($setup.startHardwareKeySetup, ["stop"]),
10466
10764
  disabled: $setup.loading,
10467
- class: "w-full"
10765
+ class: "w-full mt-4"
10468
10766
  }, {
10469
10767
  default: vue.withCtx(() => _cache[11] || (_cache[11] = [
10470
10768
  vue.createTextVNode(
@@ -10481,30 +10779,45 @@ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
10481
10779
  ])
10482
10780
  ]),
10483
10781
  vue.createCommentVNode(" Manage Existing "),
10484
- $setup.activeMfaDevices.length > 0 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_17, [
10485
- _cache[15] || (_cache[15] = vue.createElementVNode(
10486
- "h3",
10487
- { class: "text-lg font-semibold text-gray-900 mb-4" },
10488
- "Manage Existing Methods",
10489
- -1
10490
- /* CACHED */
10491
- )),
10492
- vue.createVNode($setup["StrandsUiButton"], {
10493
- variant: "secondary",
10494
- onClick: $setup.openMfaModal,
10495
- disabled: $setup.loading,
10496
- class: "w-full"
10497
- }, {
10498
- default: vue.withCtx(() => _cache[14] || (_cache[14] = [
10499
- vue.createTextVNode(
10500
- " Manage 2FA Devices ",
10782
+ $setup.activeMfaDevices.length > 0 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_16, [
10783
+ vue.createElementVNode("div", _hoisted_17, [
10784
+ vue.createElementVNode("div", null, [
10785
+ _cache[14] || (_cache[14] = vue.createElementVNode(
10786
+ "h3",
10787
+ { class: "text-lg font-semibold text-gray-900" },
10788
+ "Manage Existing Methods",
10501
10789
  -1
10502
10790
  /* CACHED */
10791
+ )),
10792
+ vue.createElementVNode(
10793
+ "p",
10794
+ _hoisted_18,
10795
+ vue.toDisplayString($setup.activeMfaDevices.length) + " device(s) currently active",
10796
+ 1
10797
+ /* TEXT */
10503
10798
  )
10504
- ])),
10505
- _: 1,
10506
- __: [14]
10507
- }, 8, ["disabled"])
10799
+ ]),
10800
+ vue.createVNode($setup["StrandsUiButton"], {
10801
+ variant: "secondary",
10802
+ size: "md",
10803
+ onClick: $setup.openMfaModal,
10804
+ disabled: $setup.loading
10805
+ }, {
10806
+ default: vue.withCtx(() => [
10807
+ vue.createVNode($setup["Settings"], {
10808
+ size: 16,
10809
+ class: "mr-2"
10810
+ }),
10811
+ _cache[15] || (_cache[15] = vue.createTextVNode(
10812
+ " Manage Devices ",
10813
+ -1
10814
+ /* CACHED */
10815
+ ))
10816
+ ]),
10817
+ _: 1,
10818
+ __: [15]
10819
+ }, 8, ["disabled"])
10820
+ ])
10508
10821
  ])) : vue.createCommentVNode("v-if", true)
10509
10822
  ])
10510
10823
  ],