@drmhse/authos-vue 0.2.7 → 0.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,15 +1,13 @@
1
- 'use strict';
2
-
3
- var vue = require('vue');
4
- var ssoSdk = require('@drmhse/sso-sdk');
5
-
6
- // src/plugin.ts
7
-
8
- // src/types.ts
9
- var AUTH_OS_INJECTION_KEY = /* @__PURE__ */ Symbol("authOS");
10
-
11
- // src/styles.ts
12
- var AUTHOS_STYLES = `
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_useAuthOS = require("./useAuthOS-PBWjiXpo.js");
3
+ let vue = require("vue");
4
+ let _drmhse_sso_sdk = require("@drmhse/sso-sdk");
5
+ //#region src/styles.ts
6
+ /**
7
+ * Built-in styles for AuthOS Vue components.
8
+ * Provides polished default styling with CSS custom properties for theming.
9
+ */
10
+ const AUTHOS_STYLES = `
13
11
  /* ==========================================================================
14
12
  AuthOS Component Styles
15
13
  CSS Variables + Default Theme
@@ -438,1252 +436,1311 @@ var AUTHOS_STYLES = `
438
436
  opacity: 0.6;
439
437
  }
440
438
  `;
441
- var stylesInjected = false;
439
+ /**
440
+ * Injects the AuthOS styles into the document head.
441
+ * Only injects once, even if called multiple times.
442
+ */
443
+ let stylesInjected = false;
442
444
  function injectStyles() {
443
- if (stylesInjected) return;
444
- if (typeof document === "undefined") return;
445
- const styleElement = document.createElement("style");
446
- styleElement.setAttribute("data-authos-styles", "");
447
- styleElement.textContent = AUTHOS_STYLES;
448
- document.head.appendChild(styleElement);
449
- stylesInjected = true;
445
+ if (stylesInjected) return;
446
+ if (typeof document === "undefined") return;
447
+ const styleElement = document.createElement("style");
448
+ styleElement.setAttribute("data-authos-styles", "");
449
+ styleElement.textContent = AUTHOS_STYLES;
450
+ document.head.appendChild(styleElement);
451
+ stylesInjected = true;
450
452
  }
453
+ /**
454
+ * Applies custom CSS variable overrides for theming.
455
+ */
451
456
  function applyVariables(variables) {
452
- if (typeof document === "undefined") return;
453
- const root = document.documentElement;
454
- for (const [key, value] of Object.entries(variables)) {
455
- const cssVar = `--authos-${key.replace(/([A-Z])/g, "-$1").toLowerCase()}`;
456
- root.style.setProperty(cssVar, value);
457
- }
457
+ if (typeof document === "undefined") return;
458
+ const root = document.documentElement;
459
+ for (const [key, value] of Object.entries(variables)) {
460
+ const cssVar = `--authos-${key.replace(/([A-Z])/g, "-$1").toLowerCase()}`;
461
+ root.style.setProperty(cssVar, value);
462
+ }
458
463
  }
459
-
460
- // src/plugin.ts
464
+ //#endregion
465
+ //#region src/plugin.ts
461
466
  function createAuthOS(options) {
462
- const getStorage = () => {
463
- if (options.storage) return options.storage;
464
- try {
465
- if (typeof window !== "undefined" && window.localStorage) {
466
- return new ssoSdk.BrowserStorage();
467
- }
468
- } catch {
469
- }
470
- return new ssoSdk.MemoryStorage();
471
- };
472
- const client = new ssoSdk.SsoClient({
473
- baseURL: options.baseURL,
474
- storage: getStorage(),
475
- token: options.initialToken
476
- // Pass initial token if provided
477
- });
478
- let hasSetInitialToken = false;
479
- const setInitialToken = async () => {
480
- if (options.initialToken && !hasSetInitialToken) {
481
- await client.setSession({ access_token: options.initialToken });
482
- hasSetInitialToken = true;
483
- }
484
- };
485
- const state = vue.reactive({
486
- user: null,
487
- isAuthenticated: false,
488
- isLoading: !options.initialToken,
489
- // Skip loading if we have initial token
490
- currentOrganization: null,
491
- organizations: []
492
- });
493
- const context = {
494
- client,
495
- state,
496
- options
497
- };
498
- return {
499
- install(app) {
500
- injectStyles();
501
- if (options.appearance?.variables) {
502
- applyVariables(options.appearance.variables);
503
- }
504
- if (options.org && !options.service) {
505
- console.warn(
506
- '[AuthOS] You provided "org" but not "service". OAuth flows may not work correctly.'
507
- );
508
- }
509
- if (!options.org && options.service) {
510
- console.warn(
511
- '[AuthOS] You provided "service" but not "org". OAuth flows may not work correctly.'
512
- );
513
- }
514
- vue.nextTick(() => {
515
- setInitialToken();
516
- });
517
- client.onAuthStateChange(async (isAuthenticated) => {
518
- state.isAuthenticated = isAuthenticated;
519
- state.isLoading = false;
520
- if (isAuthenticated) {
521
- try {
522
- const profile = await client.user.getProfile();
523
- state.user = profile;
524
- } catch {
525
- state.user = null;
526
- }
527
- try {
528
- const orgs = await client.organizations.list();
529
- state.organizations = orgs;
530
- if (orgs.length > 0 && !state.currentOrganization) {
531
- state.currentOrganization = orgs[0];
532
- }
533
- } catch {
534
- state.organizations = [];
535
- }
536
- } else {
537
- state.user = null;
538
- state.currentOrganization = null;
539
- state.organizations = [];
540
- }
541
- });
542
- app.provide(AUTH_OS_INJECTION_KEY, context);
543
- app.config.globalProperties.$authOS = context;
544
- }
545
- };
546
- }
547
- function useAuthOS() {
548
- const context = vue.inject(AUTH_OS_INJECTION_KEY);
549
- if (!context) {
550
- const defaultOptions = {
551
- baseURL: "http://localhost:3001"
552
- };
553
- const defaultClient = new ssoSdk.SsoClient({
554
- baseURL: defaultOptions.baseURL,
555
- storage: new ssoSdk.MemoryStorage()
556
- });
557
- return {
558
- client: defaultClient,
559
- options: defaultOptions,
560
- isLoading: vue.computed(() => false),
561
- isAuthenticated: vue.computed(() => false)
562
- };
563
- }
564
- const isLoading = vue.computed(() => context.state.isLoading);
565
- const isAuthenticated = vue.computed(() => context.state.isAuthenticated);
566
- return {
567
- client: context.client,
568
- options: context.options,
569
- isLoading,
570
- isAuthenticated
571
- };
467
+ const getStorage = () => {
468
+ if (options.storage) return options.storage;
469
+ try {
470
+ if (typeof window !== "undefined" && window.localStorage) return new _drmhse_sso_sdk.BrowserStorage();
471
+ } catch {}
472
+ return new _drmhse_sso_sdk.MemoryStorage();
473
+ };
474
+ const client = new _drmhse_sso_sdk.SsoClient({
475
+ baseURL: options.baseURL,
476
+ storage: getStorage(),
477
+ token: options.initialToken
478
+ });
479
+ let hasSetInitialToken = false;
480
+ const setInitialToken = async () => {
481
+ if (options.initialToken && !hasSetInitialToken) {
482
+ await client.setSession({ access_token: options.initialToken });
483
+ hasSetInitialToken = true;
484
+ }
485
+ };
486
+ const state = (0, vue.reactive)({
487
+ user: null,
488
+ isAuthenticated: false,
489
+ isLoading: !options.initialToken,
490
+ currentOrganization: null,
491
+ organizations: []
492
+ });
493
+ const context = {
494
+ client,
495
+ state,
496
+ options
497
+ };
498
+ return { install(app) {
499
+ injectStyles();
500
+ if (options.appearance?.variables) applyVariables(options.appearance.variables);
501
+ if (options.org && !options.service) console.warn("[AuthOS] You provided \"org\" but not \"service\". OAuth flows may not work correctly.");
502
+ if (!options.org && options.service) console.warn("[AuthOS] You provided \"service\" but not \"org\". OAuth flows may not work correctly.");
503
+ (0, vue.nextTick)(() => {
504
+ setInitialToken();
505
+ });
506
+ client.onAuthStateChange(async (isAuthenticated) => {
507
+ state.isAuthenticated = isAuthenticated;
508
+ state.isLoading = false;
509
+ if (isAuthenticated) {
510
+ try {
511
+ state.user = await client.user.getProfile();
512
+ } catch {
513
+ state.user = null;
514
+ }
515
+ try {
516
+ const orgs = await client.organizations.list();
517
+ state.organizations = orgs;
518
+ if (orgs.length > 0 && !state.currentOrganization) state.currentOrganization = orgs[0];
519
+ } catch {
520
+ state.organizations = [];
521
+ }
522
+ } else {
523
+ state.user = null;
524
+ state.currentOrganization = null;
525
+ state.organizations = [];
526
+ }
527
+ });
528
+ app.provide(require_useAuthOS.AUTH_OS_INJECTION_KEY, context);
529
+ app.config.globalProperties.$authOS = context;
530
+ } };
572
531
  }
532
+ //#endregion
533
+ //#region src/composables/useUser.ts
573
534
  function useUser() {
574
- const context = vue.inject(AUTH_OS_INJECTION_KEY);
575
- if (!context) {
576
- return {
577
- user: vue.ref(null),
578
- isLoading: vue.computed(() => false)
579
- };
580
- }
581
- const user = vue.computed(() => context.state.user);
582
- const isLoading = vue.computed(() => context.state.isLoading);
583
- return {
584
- user,
585
- isLoading
586
- };
535
+ const context = (0, vue.inject)(require_useAuthOS.AUTH_OS_INJECTION_KEY);
536
+ if (!context) return {
537
+ user: (0, vue.ref)(null),
538
+ isLoading: (0, vue.computed)(() => false)
539
+ };
540
+ return {
541
+ user: (0, vue.computed)(() => context.state.user),
542
+ isLoading: (0, vue.computed)(() => context.state.isLoading)
543
+ };
587
544
  }
545
+ //#endregion
546
+ //#region src/composables/useOrganization.ts
547
+ /**
548
+ * Composable to access the current organization context and switch between organizations.
549
+ *
550
+ * When switching organizations, this calls the backend to issue new JWT tokens
551
+ * with the organization context, enabling seamless organization switching without
552
+ * requiring re-authentication.
553
+ *
554
+ * @returns The current organization and a function to switch organizations
555
+ *
556
+ * @example
557
+ * ```vue
558
+ * <script setup>
559
+ * import { useOrganization } from '@drmhse/authos-vue';
560
+ *
561
+ * const { currentOrganization, switchOrganization, isSwitching } = useOrganization();
562
+ * <\/script>
563
+ * ```
564
+ */
588
565
  function useOrganization() {
589
- const context = vue.inject(AUTH_OS_INJECTION_KEY);
590
- if (!context) {
591
- return {
592
- currentOrganization: vue.ref(null),
593
- organizations: vue.ref([]),
594
- switchOrganization: async () => null,
595
- isSwitching: vue.ref(false)
596
- };
597
- }
598
- const currentOrganization = vue.computed(() => context.state.currentOrganization);
599
- const organizations = vue.computed(() => context.state.organizations);
600
- const isSwitching = vue.ref(false);
601
- async function switchOrganization(slug) {
602
- if (!context) return;
603
- isSwitching.value = true;
604
- try {
605
- const result = await context.client.organizations.select(slug);
606
- await context.client.setSession({
607
- access_token: result.access_token,
608
- refresh_token: result.refresh_token
609
- });
610
- const orgResponse = await context.client.organizations.get(slug);
611
- context.state.currentOrganization = orgResponse;
612
- return orgResponse;
613
- } finally {
614
- isSwitching.value = false;
615
- }
616
- }
617
- return {
618
- currentOrganization,
619
- organizations,
620
- switchOrganization,
621
- isSwitching
622
- };
566
+ const context = (0, vue.inject)(require_useAuthOS.AUTH_OS_INJECTION_KEY);
567
+ if (!context) return {
568
+ currentOrganization: (0, vue.ref)(null),
569
+ organizations: (0, vue.ref)([]),
570
+ switchOrganization: async () => null,
571
+ isSwitching: (0, vue.ref)(false)
572
+ };
573
+ const currentOrganization = (0, vue.computed)(() => context.state.currentOrganization);
574
+ const organizations = (0, vue.computed)(() => context.state.organizations);
575
+ const isSwitching = (0, vue.ref)(false);
576
+ async function switchOrganization(slug) {
577
+ if (!context) return;
578
+ isSwitching.value = true;
579
+ try {
580
+ const result = await context.client.organizations.select(slug);
581
+ await context.client.setSession({
582
+ access_token: result.access_token,
583
+ refresh_token: result.refresh_token
584
+ });
585
+ const orgResponse = await context.client.organizations.get(slug);
586
+ context.state.currentOrganization = orgResponse;
587
+ return orgResponse;
588
+ } finally {
589
+ isSwitching.value = false;
590
+ }
591
+ }
592
+ return {
593
+ currentOrganization,
594
+ organizations,
595
+ switchOrganization,
596
+ isSwitching
597
+ };
623
598
  }
599
+ //#endregion
600
+ //#region src/composables/usePermission.ts
601
+ /**
602
+ * Check if the current user has a specific permission.
603
+ *
604
+ * @param permission The permission to check
605
+ * @returns A computed ref that is true if the user has the permission
606
+ *
607
+ * @example
608
+ * ```vue
609
+ * <script setup>
610
+ * import { usePermission } from '@drmhse/authos-vue';
611
+ *
612
+ * const canAccessAdmin = usePermission('admin:access');
613
+ * <\/script>
614
+ *
615
+ * <template>
616
+ * <button v-if="canAccessAdmin">Admin Panel</button>
617
+ * </template>
618
+ * ```
619
+ */
624
620
  function usePermission(permission) {
625
- const { user } = useUser();
626
- return vue.computed(() => {
627
- if (!user.value || !permission) return false;
628
- return user.value.permissions?.includes(permission) ?? false;
629
- });
621
+ const { user } = useUser();
622
+ return (0, vue.computed)(() => {
623
+ if (!user.value || !permission) return false;
624
+ return user.value.permissions?.includes(permission) ?? false;
625
+ });
630
626
  }
627
+ /**
628
+ * Check if the current user has any of the specified permissions.
629
+ *
630
+ * @param permissions The permissions to check
631
+ * @returns A computed ref that is true if the user has any of the permissions
632
+ *
633
+ * @example
634
+ * ```vue
635
+ * <script setup>
636
+ * import { useAnyPermission } from '@drmhse/authos-vue';
637
+ *
638
+ * const canAccessReports = useAnyPermission(['reports:read', 'admin:access']);
639
+ * <\/script>
640
+ * ```
641
+ */
631
642
  function useAnyPermission(permissions) {
632
- const { user } = useUser();
633
- return vue.computed(() => {
634
- if (!user.value || permissions.length === 0) return false;
635
- return permissions.some((p) => user.value?.permissions?.includes(p));
636
- });
643
+ const { user } = useUser();
644
+ return (0, vue.computed)(() => {
645
+ if (!user.value || permissions.length === 0) return false;
646
+ return permissions.some((p) => user.value?.permissions?.includes(p));
647
+ });
637
648
  }
649
+ /**
650
+ * Check if the current user has all of the specified permissions.
651
+ *
652
+ * @param permissions The permissions to check
653
+ * @returns A computed ref that is true if the user has all of the permissions
654
+ *
655
+ * @example
656
+ * ```vue
657
+ * <script setup>
658
+ * import { useAllPermissions } from '@drmhse/authos-vue';
659
+ *
660
+ * const canManageBilling = useAllPermissions(['billing:read', 'billing:write']);
661
+ * <\/script>
662
+ * ```
663
+ */
638
664
  function useAllPermissions(permissions) {
639
- const { user } = useUser();
640
- return vue.computed(() => {
641
- if (!user.value || permissions.length === 0) return false;
642
- return permissions.every((p) => user.value?.permissions?.includes(p));
643
- });
665
+ const { user } = useUser();
666
+ return (0, vue.computed)(() => {
667
+ if (!user.value || permissions.length === 0) return false;
668
+ return permissions.every((p) => user.value?.permissions?.includes(p));
669
+ });
644
670
  }
645
- var AuthOSProvider = vue.defineComponent({
646
- name: "AuthOSProvider",
647
- props: {
648
- baseURL: {
649
- type: String,
650
- required: true
651
- },
652
- org: {
653
- type: String,
654
- default: void 0
655
- },
656
- service: {
657
- type: String,
658
- default: void 0
659
- },
660
- redirectUri: {
661
- type: String,
662
- default: void 0
663
- },
664
- storage: {
665
- type: Object,
666
- default: void 0
667
- },
668
- client: {
669
- type: Object,
670
- default: void 0
671
- }
672
- },
673
- setup(props, { slots }) {
674
- const getStorage = () => {
675
- if (props.storage) return props.storage;
676
- if (typeof window !== "undefined") return new ssoSdk.BrowserStorage();
677
- return new ssoSdk.MemoryStorage();
678
- };
679
- const client = props.client ?? new ssoSdk.SsoClient({
680
- baseURL: props.baseURL,
681
- storage: getStorage()
682
- });
683
- const state = vue.reactive({
684
- user: null,
685
- isAuthenticated: false,
686
- isLoading: true,
687
- currentOrganization: null,
688
- organizations: []
689
- });
690
- const options = {
691
- baseURL: props.baseURL,
692
- org: props.org,
693
- service: props.service,
694
- redirectUri: props.redirectUri
695
- };
696
- const context = { client, state, options };
697
- vue.provide(AUTH_OS_INJECTION_KEY, context);
698
- let unsubscribe;
699
- vue.onMounted(() => {
700
- unsubscribe = client.onAuthStateChange(async (isAuthenticated) => {
701
- state.isAuthenticated = isAuthenticated;
702
- state.isLoading = false;
703
- if (isAuthenticated) {
704
- try {
705
- const profile = await client.user.getProfile();
706
- state.user = profile;
707
- } catch {
708
- state.user = null;
709
- }
710
- try {
711
- const orgs = await client.organizations.list();
712
- state.organizations = orgs;
713
- if (orgs.length > 0 && !state.currentOrganization) {
714
- state.currentOrganization = orgs[0];
715
- }
716
- } catch {
717
- state.organizations = [];
718
- }
719
- } else {
720
- state.user = null;
721
- state.currentOrganization = null;
722
- state.organizations = [];
723
- }
724
- });
725
- });
726
- vue.onUnmounted(() => {
727
- unsubscribe?.();
728
- });
729
- return () => slots.default ? slots.default() : vue.h("div");
730
- }
671
+ //#endregion
672
+ //#region src/components/AuthOSProvider.ts
673
+ const AuthOSProvider = (0, vue.defineComponent)({
674
+ name: "AuthOSProvider",
675
+ props: {
676
+ baseURL: {
677
+ type: String,
678
+ required: true
679
+ },
680
+ org: {
681
+ type: String,
682
+ default: void 0
683
+ },
684
+ service: {
685
+ type: String,
686
+ default: void 0
687
+ },
688
+ redirectUri: {
689
+ type: String,
690
+ default: void 0
691
+ },
692
+ storage: {
693
+ type: Object,
694
+ default: void 0
695
+ },
696
+ client: {
697
+ type: Object,
698
+ default: void 0
699
+ }
700
+ },
701
+ setup(props, { slots }) {
702
+ const getStorage = () => {
703
+ if (props.storage) return props.storage;
704
+ if (typeof window !== "undefined") return new _drmhse_sso_sdk.BrowserStorage();
705
+ return new _drmhse_sso_sdk.MemoryStorage();
706
+ };
707
+ const client = props.client ?? new _drmhse_sso_sdk.SsoClient({
708
+ baseURL: props.baseURL,
709
+ storage: getStorage()
710
+ });
711
+ const state = (0, vue.reactive)({
712
+ user: null,
713
+ isAuthenticated: false,
714
+ isLoading: true,
715
+ currentOrganization: null,
716
+ organizations: []
717
+ });
718
+ (0, vue.provide)(require_useAuthOS.AUTH_OS_INJECTION_KEY, {
719
+ client,
720
+ state,
721
+ options: {
722
+ baseURL: props.baseURL,
723
+ org: props.org,
724
+ service: props.service,
725
+ redirectUri: props.redirectUri
726
+ }
727
+ });
728
+ let unsubscribe;
729
+ (0, vue.onMounted)(() => {
730
+ unsubscribe = client.onAuthStateChange(async (isAuthenticated) => {
731
+ state.isAuthenticated = isAuthenticated;
732
+ state.isLoading = false;
733
+ if (isAuthenticated) {
734
+ try {
735
+ state.user = await client.user.getProfile();
736
+ } catch {
737
+ state.user = null;
738
+ }
739
+ try {
740
+ const orgs = await client.organizations.list();
741
+ state.organizations = orgs;
742
+ if (orgs.length > 0 && !state.currentOrganization) state.currentOrganization = orgs[0];
743
+ } catch {
744
+ state.organizations = [];
745
+ }
746
+ } else {
747
+ state.user = null;
748
+ state.currentOrganization = null;
749
+ state.organizations = [];
750
+ }
751
+ });
752
+ });
753
+ (0, vue.onUnmounted)(() => {
754
+ unsubscribe?.();
755
+ });
756
+ return () => slots.default ? slots.default() : (0, vue.h)("div");
757
+ }
731
758
  });
732
- var MFA_PREAUTH_EXPIRY = 300;
733
- var SignIn = vue.defineComponent({
734
- name: "SignIn",
735
- props: {
736
- onSuccess: {
737
- type: Function,
738
- default: void 0
739
- },
740
- onError: {
741
- type: Function,
742
- default: void 0
743
- }
744
- },
745
- emits: ["success", "error"],
746
- setup(props, { slots, emit }) {
747
- const { client, options } = useAuthOS();
748
- const email = vue.ref("");
749
- const password = vue.ref("");
750
- const mfaCode = vue.ref("");
751
- const preauthToken = vue.ref("");
752
- const step = vue.ref("credentials");
753
- const error = vue.ref(null);
754
- const isSubmitting = vue.ref(false);
755
- async function submit() {
756
- error.value = null;
757
- isSubmitting.value = true;
758
- try {
759
- if (step.value === "credentials") {
760
- const result = await client.auth.login({
761
- email: email.value,
762
- password: password.value,
763
- org_slug: options.org,
764
- service_slug: options.service
765
- });
766
- if (result.expires_in === MFA_PREAUTH_EXPIRY) {
767
- preauthToken.value = result.access_token;
768
- step.value = "mfa";
769
- } else {
770
- emit("success");
771
- props.onSuccess?.();
772
- }
773
- } else {
774
- await client.auth.verifyMfa(preauthToken.value, mfaCode.value);
775
- emit("success");
776
- props.onSuccess?.();
777
- }
778
- } catch (err) {
779
- const message = err instanceof ssoSdk.SsoApiError ? err.message : "Login failed";
780
- error.value = message;
781
- const e = err instanceof Error ? err : new Error(message);
782
- emit("error", e);
783
- props.onError?.(e);
784
- } finally {
785
- isSubmitting.value = false;
786
- }
787
- }
788
- return () => {
789
- const slotProps = {
790
- email: email.value,
791
- password: password.value,
792
- mfaCode: mfaCode.value,
793
- step: step.value,
794
- error: error.value,
795
- isSubmitting: isSubmitting.value,
796
- updateEmail: (v) => email.value = v,
797
- updatePassword: (v) => password.value = v,
798
- updateMfaCode: (v) => mfaCode.value = v,
799
- submit
800
- };
801
- if (slots.default) {
802
- return slots.default(slotProps);
803
- }
804
- if (step.value === "mfa") {
805
- return vue.h("div", { "data-authos-signin": "", "data-state": "mfa" }, [
806
- vue.h("form", { onSubmit: (e) => {
807
- e.preventDefault();
808
- submit();
809
- } }, [
810
- vue.h("div", { "data-authos-field": "mfa-code" }, [
811
- vue.h("label", { for: "authos-mfa-code" }, "Verification Code"),
812
- vue.h("input", {
813
- id: "authos-mfa-code",
814
- type: "text",
815
- inputMode: "numeric",
816
- autocomplete: "one-time-code",
817
- value: mfaCode.value,
818
- placeholder: "Enter 6-digit code",
819
- required: true,
820
- disabled: isSubmitting.value,
821
- onInput: (e) => mfaCode.value = e.target.value
822
- })
823
- ]),
824
- error.value && vue.h("div", { "data-authos-error": "" }, error.value),
825
- vue.h("button", {
826
- type: "submit",
827
- disabled: isSubmitting.value,
828
- "data-authos-submit": ""
829
- }, isSubmitting.value ? "Verifying..." : "Verify"),
830
- vue.h("button", {
831
- type: "button",
832
- "data-authos-back": "",
833
- onClick: () => {
834
- step.value = "credentials";
835
- mfaCode.value = "";
836
- preauthToken.value = "";
837
- error.value = null;
838
- }
839
- }, "Back to login")
840
- ])
841
- ]);
842
- }
843
- return vue.h("div", { "data-authos-signin": "", "data-state": "credentials" }, [
844
- vue.h("form", { onSubmit: (e) => {
845
- e.preventDefault();
846
- submit();
847
- } }, [
848
- vue.h("div", { "data-authos-field": "email" }, [
849
- vue.h("label", { for: "authos-email" }, "Email"),
850
- vue.h("input", {
851
- id: "authos-email",
852
- type: "email",
853
- autocomplete: "email",
854
- value: email.value,
855
- placeholder: "Enter your email",
856
- required: true,
857
- disabled: isSubmitting.value,
858
- onInput: (e) => email.value = e.target.value
859
- })
860
- ]),
861
- vue.h("div", { "data-authos-field": "password" }, [
862
- vue.h("label", { for: "authos-password" }, "Password"),
863
- vue.h("input", {
864
- id: "authos-password",
865
- type: "password",
866
- autocomplete: "current-password",
867
- value: password.value,
868
- placeholder: "Enter your password",
869
- required: true,
870
- disabled: isSubmitting.value,
871
- onInput: (e) => password.value = e.target.value
872
- })
873
- ]),
874
- error.value && vue.h("div", { "data-authos-error": "" }, error.value),
875
- vue.h("button", {
876
- type: "submit",
877
- disabled: isSubmitting.value,
878
- "data-authos-submit": ""
879
- }, isSubmitting.value ? "Signing in..." : "Sign In")
880
- ])
881
- ]);
882
- };
883
- }
759
+ //#endregion
760
+ //#region src/components/SignIn.ts
761
+ const MFA_PREAUTH_EXPIRY = 300;
762
+ const SignIn = (0, vue.defineComponent)({
763
+ name: "SignIn",
764
+ props: {
765
+ onSuccess: {
766
+ type: Function,
767
+ default: void 0
768
+ },
769
+ onError: {
770
+ type: Function,
771
+ default: void 0
772
+ }
773
+ },
774
+ emits: ["success", "error"],
775
+ setup(props, { slots, emit }) {
776
+ const { client, options } = require_useAuthOS.useAuthOS();
777
+ const email = (0, vue.ref)("");
778
+ const password = (0, vue.ref)("");
779
+ const mfaCode = (0, vue.ref)("");
780
+ const preauthToken = (0, vue.ref)("");
781
+ const step = (0, vue.ref)("credentials");
782
+ const error = (0, vue.ref)(null);
783
+ const isSubmitting = (0, vue.ref)(false);
784
+ async function submit() {
785
+ error.value = null;
786
+ isSubmitting.value = true;
787
+ try {
788
+ if (step.value === "credentials") {
789
+ const result = await client.auth.login({
790
+ email: email.value,
791
+ password: password.value,
792
+ org_slug: options.org,
793
+ service_slug: options.service
794
+ });
795
+ if (result.expires_in === MFA_PREAUTH_EXPIRY) {
796
+ preauthToken.value = result.access_token;
797
+ step.value = "mfa";
798
+ } else {
799
+ emit("success");
800
+ props.onSuccess?.();
801
+ }
802
+ } else {
803
+ await client.auth.verifyMfa(preauthToken.value, mfaCode.value);
804
+ emit("success");
805
+ props.onSuccess?.();
806
+ }
807
+ } catch (err) {
808
+ const message = err instanceof _drmhse_sso_sdk.SsoApiError ? err.message : "Login failed";
809
+ error.value = message;
810
+ const e = err instanceof Error ? err : new Error(message);
811
+ emit("error", e);
812
+ props.onError?.(e);
813
+ } finally {
814
+ isSubmitting.value = false;
815
+ }
816
+ }
817
+ return () => {
818
+ const slotProps = {
819
+ email: email.value,
820
+ password: password.value,
821
+ mfaCode: mfaCode.value,
822
+ step: step.value,
823
+ error: error.value,
824
+ isSubmitting: isSubmitting.value,
825
+ updateEmail: (v) => email.value = v,
826
+ updatePassword: (v) => password.value = v,
827
+ updateMfaCode: (v) => mfaCode.value = v,
828
+ submit
829
+ };
830
+ if (slots.default) return slots.default(slotProps);
831
+ if (step.value === "mfa") return (0, vue.h)("div", {
832
+ "data-authos-signin": "",
833
+ "data-state": "mfa"
834
+ }, [(0, vue.h)("form", { onSubmit: (e) => {
835
+ e.preventDefault();
836
+ submit();
837
+ } }, [
838
+ (0, vue.h)("div", { "data-authos-field": "mfa-code" }, [(0, vue.h)("label", { for: "authos-mfa-code" }, "Verification Code"), (0, vue.h)("input", {
839
+ id: "authos-mfa-code",
840
+ type: "text",
841
+ inputMode: "numeric",
842
+ autocomplete: "one-time-code",
843
+ value: mfaCode.value,
844
+ placeholder: "Enter 6-digit code",
845
+ required: true,
846
+ disabled: isSubmitting.value,
847
+ onInput: (e) => mfaCode.value = e.target.value
848
+ })]),
849
+ error.value && (0, vue.h)("div", { "data-authos-error": "" }, error.value),
850
+ (0, vue.h)("button", {
851
+ type: "submit",
852
+ disabled: isSubmitting.value,
853
+ "data-authos-submit": ""
854
+ }, isSubmitting.value ? "Verifying..." : "Verify"),
855
+ (0, vue.h)("button", {
856
+ type: "button",
857
+ "data-authos-back": "",
858
+ onClick: () => {
859
+ step.value = "credentials";
860
+ mfaCode.value = "";
861
+ preauthToken.value = "";
862
+ error.value = null;
863
+ }
864
+ }, "Back to login")
865
+ ])]);
866
+ return (0, vue.h)("div", {
867
+ "data-authos-signin": "",
868
+ "data-state": "credentials"
869
+ }, [(0, vue.h)("form", { onSubmit: (e) => {
870
+ e.preventDefault();
871
+ submit();
872
+ } }, [
873
+ (0, vue.h)("div", { "data-authos-field": "email" }, [(0, vue.h)("label", { for: "authos-email" }, "Email"), (0, vue.h)("input", {
874
+ id: "authos-email",
875
+ type: "email",
876
+ autocomplete: "email",
877
+ value: email.value,
878
+ placeholder: "Enter your email",
879
+ required: true,
880
+ disabled: isSubmitting.value,
881
+ onInput: (e) => email.value = e.target.value
882
+ })]),
883
+ (0, vue.h)("div", { "data-authos-field": "password" }, [(0, vue.h)("label", { for: "authos-password" }, "Password"), (0, vue.h)("input", {
884
+ id: "authos-password",
885
+ type: "password",
886
+ autocomplete: "current-password",
887
+ value: password.value,
888
+ placeholder: "Enter your password",
889
+ required: true,
890
+ disabled: isSubmitting.value,
891
+ onInput: (e) => password.value = e.target.value
892
+ })]),
893
+ error.value && (0, vue.h)("div", { "data-authos-error": "" }, error.value),
894
+ (0, vue.h)("button", {
895
+ type: "submit",
896
+ disabled: isSubmitting.value,
897
+ "data-authos-submit": ""
898
+ }, isSubmitting.value ? "Signing in..." : "Sign In")
899
+ ])]);
900
+ };
901
+ }
884
902
  });
885
- var PROVIDER_NAMES = {
886
- github: "GitHub",
887
- google: "Google",
888
- microsoft: "Microsoft"
903
+ //#endregion
904
+ //#region src/components/OAuthButton.ts
905
+ /**
906
+ * Human-readable provider names for button labels
907
+ */
908
+ const PROVIDER_NAMES = {
909
+ github: "GitHub",
910
+ google: "Google",
911
+ microsoft: "Microsoft"
889
912
  };
913
+ /**
914
+ * SVG icons for each OAuth provider
915
+ */
890
916
  function getProviderIcon(provider) {
891
- switch (provider) {
892
- case "github":
893
- return vue.h("svg", {
894
- xmlns: "http://www.w3.org/2000/svg",
895
- viewBox: "0 0 24 24",
896
- fill: "currentColor",
897
- "aria-hidden": "true"
898
- }, [
899
- vue.h("path", {
900
- d: "M12 0C5.374 0 0 5.373 0 12c0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z"
901
- })
902
- ]);
903
- case "google":
904
- return vue.h("svg", {
905
- xmlns: "http://www.w3.org/2000/svg",
906
- viewBox: "0 0 24 24",
907
- "aria-hidden": "true"
908
- }, [
909
- vue.h("path", {
910
- fill: "#4285F4",
911
- d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
912
- }),
913
- vue.h("path", {
914
- fill: "#34A853",
915
- d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
916
- }),
917
- vue.h("path", {
918
- fill: "#FBBC05",
919
- d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
920
- }),
921
- vue.h("path", {
922
- fill: "#EA4335",
923
- d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
924
- })
925
- ]);
926
- case "microsoft":
927
- return vue.h("svg", {
928
- xmlns: "http://www.w3.org/2000/svg",
929
- viewBox: "0 0 23 23",
930
- "aria-hidden": "true"
931
- }, [
932
- vue.h("path", { fill: "#f35325", d: "M1 1h10v10H1z" }),
933
- vue.h("path", { fill: "#81bc06", d: "M12 1h10v10H12z" }),
934
- vue.h("path", { fill: "#05a6f0", d: "M1 12h10v10H1z" }),
935
- vue.h("path", { fill: "#ffba08", d: "M12 12h10v10H12z" })
936
- ]);
937
- }
917
+ switch (provider) {
918
+ case "github": return (0, vue.h)("svg", {
919
+ xmlns: "http://www.w3.org/2000/svg",
920
+ viewBox: "0 0 24 24",
921
+ fill: "currentColor",
922
+ "aria-hidden": "true"
923
+ }, [(0, vue.h)("path", { d: "M12 0C5.374 0 0 5.373 0 12c0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0112 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z" })]);
924
+ case "google": return (0, vue.h)("svg", {
925
+ xmlns: "http://www.w3.org/2000/svg",
926
+ viewBox: "0 0 24 24",
927
+ "aria-hidden": "true"
928
+ }, [
929
+ (0, vue.h)("path", {
930
+ fill: "#4285F4",
931
+ d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
932
+ }),
933
+ (0, vue.h)("path", {
934
+ fill: "#34A853",
935
+ d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
936
+ }),
937
+ (0, vue.h)("path", {
938
+ fill: "#FBBC05",
939
+ d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
940
+ }),
941
+ (0, vue.h)("path", {
942
+ fill: "#EA4335",
943
+ d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
944
+ })
945
+ ]);
946
+ case "microsoft": return (0, vue.h)("svg", {
947
+ xmlns: "http://www.w3.org/2000/svg",
948
+ viewBox: "0 0 23 23",
949
+ "aria-hidden": "true"
950
+ }, [
951
+ (0, vue.h)("path", {
952
+ fill: "#f35325",
953
+ d: "M1 1h10v10H1z"
954
+ }),
955
+ (0, vue.h)("path", {
956
+ fill: "#81bc06",
957
+ d: "M12 1h10v10H12z"
958
+ }),
959
+ (0, vue.h)("path", {
960
+ fill: "#05a6f0",
961
+ d: "M1 12h10v10H1z"
962
+ }),
963
+ (0, vue.h)("path", {
964
+ fill: "#ffba08",
965
+ d: "M12 12h10v10H12z"
966
+ })
967
+ ]);
968
+ }
938
969
  }
939
- var OAuthButton = vue.defineComponent({
940
- name: "OAuthButton",
941
- props: {
942
- provider: {
943
- type: String,
944
- required: true
945
- },
946
- disabled: {
947
- type: Boolean,
948
- default: false
949
- }
950
- },
951
- emits: ["redirect"],
952
- setup(props, { slots, emit }) {
953
- const { client, options } = useAuthOS();
954
- const isConfigured = vue.computed(() => !!(options.org && options.service));
955
- const providerName = vue.computed(() => PROVIDER_NAMES[props.provider]);
956
- function handleClick() {
957
- if (!options.org || !options.service) {
958
- console.error(
959
- `[AuthOS] OAuth login requires "org" and "service" in createAuthOS options.
960
- Current options: { org: ${options.org ? `"${options.org}"` : "undefined"}, service: ${options.service ? `"${options.service}"` : "undefined"} }
961
-
962
- Example:
963
- app.use(createAuthOS({
964
- baseURL: "${options.baseURL}",
965
- org: "your-org-slug",
966
- service: "your-service-slug",
967
- }));
968
-
969
- See: https://docs.authos.dev/vue/oauth-setup`
970
- );
971
- return;
972
- }
973
- const redirectUri = options.redirectUri ?? (typeof window !== "undefined" ? window.location.origin + "/callback" : void 0);
974
- const url = client.auth.getLoginUrl(props.provider, {
975
- org: options.org,
976
- service: options.service,
977
- redirect_uri: redirectUri
978
- });
979
- emit("redirect");
980
- window.location.href = url;
981
- }
982
- return () => {
983
- const slotProps = {
984
- provider: props.provider,
985
- providerName: providerName.value,
986
- isConfigured: isConfigured.value,
987
- disabled: props.disabled,
988
- handleClick
989
- };
990
- if (slots.default) {
991
- return slots.default(slotProps);
992
- }
993
- return vue.h(
994
- "button",
995
- {
996
- type: "button",
997
- onClick: handleClick,
998
- disabled: props.disabled || !isConfigured.value,
999
- "data-authos-oauth": "",
1000
- "data-provider": props.provider
1001
- },
1002
- [
1003
- getProviderIcon(props.provider),
1004
- vue.h("span", `Continue with ${providerName.value}`)
1005
- ]
1006
- );
1007
- };
1008
- }
970
+ /**
971
+ * OAuth login button for a specific provider.
972
+ * Redirects the user to the OAuth provider's login page.
973
+ *
974
+ * Requires `org` and `service` to be configured in createAuthOS options.
975
+ *
976
+ * @example
977
+ * ```vue
978
+ * <script setup>
979
+ * import { OAuthButton } from '@drmhse/authos-vue';
980
+ * <\/script>
981
+ *
982
+ * <template>
983
+ * <OAuthButton provider="github" />
984
+ * <OAuthButton provider="google">Sign in with Google</OAuthButton>
985
+ * </template>
986
+ * ```
987
+ */
988
+ const OAuthButton = (0, vue.defineComponent)({
989
+ name: "OAuthButton",
990
+ props: {
991
+ provider: {
992
+ type: String,
993
+ required: true
994
+ },
995
+ disabled: {
996
+ type: Boolean,
997
+ default: false
998
+ }
999
+ },
1000
+ emits: ["redirect"],
1001
+ setup(props, { slots, emit }) {
1002
+ const { client, options } = require_useAuthOS.useAuthOS();
1003
+ const isConfigured = (0, vue.computed)(() => !!(options.org && options.service));
1004
+ const providerName = (0, vue.computed)(() => PROVIDER_NAMES[props.provider]);
1005
+ function handleClick() {
1006
+ if (!options.org || !options.service) {
1007
+ console.error(`[AuthOS] OAuth login requires "org" and "service" in createAuthOS options.\nCurrent options: { org: ${options.org ? `"${options.org}"` : "undefined"}, service: ${options.service ? `"${options.service}"` : "undefined"} }\n\nExample:\n app.use(createAuthOS({\n baseURL: "${options.baseURL}",\n org: "your-org-slug",\n service: "your-service-slug",\n }));\n\nSee: https://docs.authos.dev/vue/oauth-setup`);
1008
+ return;
1009
+ }
1010
+ const redirectUri = options.redirectUri ?? (typeof window !== "undefined" ? window.location.origin + "/callback" : void 0);
1011
+ const url = client.auth.getLoginUrl(props.provider, {
1012
+ org: options.org,
1013
+ service: options.service,
1014
+ redirect_uri: redirectUri
1015
+ });
1016
+ emit("redirect");
1017
+ window.location.href = url;
1018
+ }
1019
+ return () => {
1020
+ const slotProps = {
1021
+ provider: props.provider,
1022
+ providerName: providerName.value,
1023
+ isConfigured: isConfigured.value,
1024
+ disabled: props.disabled,
1025
+ handleClick
1026
+ };
1027
+ if (slots.default) return slots.default(slotProps);
1028
+ return (0, vue.h)("button", {
1029
+ type: "button",
1030
+ onClick: handleClick,
1031
+ disabled: props.disabled || !isConfigured.value,
1032
+ "data-authos-oauth": "",
1033
+ "data-provider": props.provider
1034
+ }, [getProviderIcon(props.provider), (0, vue.h)("span", `Continue with ${providerName.value}`)]);
1035
+ };
1036
+ }
1009
1037
  });
1010
-
1011
- // src/components/SignUp.ts
1012
- var SignUp = vue.defineComponent({
1013
- name: "SignUp",
1014
- props: {
1015
- onSuccess: {
1016
- type: Function,
1017
- default: void 0
1018
- },
1019
- onError: {
1020
- type: Function,
1021
- default: void 0
1022
- },
1023
- /** Organization slug for tenant context */
1024
- orgSlug: {
1025
- type: String,
1026
- default: void 0
1027
- },
1028
- /** Service slug for tenant attribution (used with orgSlug) */
1029
- serviceSlug: {
1030
- type: String,
1031
- default: void 0
1032
- },
1033
- /** List of OAuth providers to display buttons for */
1034
- providers: {
1035
- type: [Array, Boolean],
1036
- default: false
1037
- },
1038
- /** Show divider between OAuth and email form */
1039
- showDivider: {
1040
- type: Boolean,
1041
- default: true
1042
- },
1043
- /** Show sign in link */
1044
- showSignIn: {
1045
- type: Boolean,
1046
- default: true
1047
- }
1048
- },
1049
- emits: ["success", "error"],
1050
- setup(props, { slots, emit }) {
1051
- const { client, options } = useAuthOS();
1052
- const email = vue.ref("");
1053
- const password = vue.ref("");
1054
- const confirmPassword = vue.ref("");
1055
- const error = vue.ref(null);
1056
- const isSubmitting = vue.ref(false);
1057
- const isSuccess = vue.ref(false);
1058
- const hasOAuthConfig = !!(options.org && options.service);
1059
- const oauthProviders = Array.isArray(props.providers) ? props.providers : [];
1060
- async function submit() {
1061
- error.value = null;
1062
- if (password.value !== confirmPassword.value) {
1063
- error.value = "Passwords do not match";
1064
- return;
1065
- }
1066
- if (password.value.length < 8) {
1067
- error.value = "Password must be at least 8 characters";
1068
- return;
1069
- }
1070
- isSubmitting.value = true;
1071
- try {
1072
- await client.auth.register({
1073
- email: email.value,
1074
- password: password.value,
1075
- org_slug: props.orgSlug ?? options.org,
1076
- service_slug: props.serviceSlug ?? options.service
1077
- });
1078
- isSuccess.value = true;
1079
- emit("success");
1080
- props.onSuccess?.();
1081
- } catch (err) {
1082
- const message = err instanceof ssoSdk.SsoApiError ? err.message : "Registration failed";
1083
- error.value = message;
1084
- const e = err instanceof Error ? err : new Error(message);
1085
- emit("error", e);
1086
- props.onError?.(e);
1087
- } finally {
1088
- isSubmitting.value = false;
1089
- }
1090
- }
1091
- return () => {
1092
- const slotProps = {
1093
- email: email.value,
1094
- password: password.value,
1095
- error: error.value,
1096
- isSubmitting: isSubmitting.value,
1097
- updateEmail: (v) => email.value = v,
1098
- updatePassword: (v) => password.value = v,
1099
- submit
1100
- };
1101
- if (slots.default) {
1102
- return slots.default(slotProps);
1103
- }
1104
- if (isSuccess.value) {
1105
- return vue.h("div", { "data-authos-signup": "", "data-state": "success" }, [
1106
- vue.h("div", { "data-authos-success": "" }, [
1107
- vue.h("h2", "Check your email"),
1108
- vue.h("p", `We've sent a verification link to ${email.value}. Please click the link to verify your account.`)
1109
- ])
1110
- ]);
1111
- }
1112
- return vue.h("div", { "data-authos-signup": "", "data-state": "credentials" }, [
1113
- // OAuth Section
1114
- oauthProviders.length > 0 && vue.h("div", { "data-authos-oauth-section": "" }, [
1115
- oauthProviders.map(
1116
- (provider) => vue.h(OAuthButton, {
1117
- key: provider,
1118
- provider,
1119
- disabled: isSubmitting.value || !hasOAuthConfig
1120
- })
1121
- ),
1122
- !hasOAuthConfig && vue.h("p", {
1123
- "data-authos-oauth-warning": "",
1124
- style: { color: "orange", fontSize: "0.875rem" }
1125
- }, "OAuth requires org and service in plugin options")
1126
- ]),
1127
- // Divider
1128
- oauthProviders.length > 0 && props.showDivider && vue.h("div", { "data-authos-divider": "" }, [
1129
- vue.h("span", "or")
1130
- ]),
1131
- vue.h("form", { onSubmit: (e) => {
1132
- e.preventDefault();
1133
- submit();
1134
- } }, [
1135
- vue.h("div", { "data-authos-field": "email" }, [
1136
- vue.h("label", { for: "authos-signup-email" }, "Email"),
1137
- vue.h("input", {
1138
- id: "authos-signup-email",
1139
- type: "email",
1140
- autocomplete: "email",
1141
- value: email.value,
1142
- placeholder: "Enter your email",
1143
- required: true,
1144
- disabled: isSubmitting.value,
1145
- onInput: (e) => email.value = e.target.value
1146
- })
1147
- ]),
1148
- vue.h("div", { "data-authos-field": "password" }, [
1149
- vue.h("label", { for: "authos-signup-password" }, "Password"),
1150
- vue.h("input", {
1151
- id: "authos-signup-password",
1152
- type: "password",
1153
- autocomplete: "new-password",
1154
- value: password.value,
1155
- placeholder: "Create a password",
1156
- required: true,
1157
- disabled: isSubmitting.value,
1158
- onInput: (e) => password.value = e.target.value
1159
- })
1160
- ]),
1161
- // Confirm Password
1162
- vue.h("div", { "data-authos-field": "confirm-password" }, [
1163
- vue.h("label", { for: "authos-signup-confirm" }, "Confirm Password"),
1164
- vue.h("input", {
1165
- id: "authos-signup-confirm",
1166
- type: "password",
1167
- autocomplete: "new-password",
1168
- value: confirmPassword.value,
1169
- placeholder: "Confirm your password",
1170
- required: true,
1171
- disabled: isSubmitting.value,
1172
- onInput: (e) => confirmPassword.value = e.target.value
1173
- })
1174
- ]),
1175
- error.value && vue.h("div", { "data-authos-error": "" }, error.value),
1176
- vue.h("button", {
1177
- type: "submit",
1178
- disabled: isSubmitting.value,
1179
- "data-authos-submit": ""
1180
- }, isSubmitting.value ? "Creating account..." : "Sign Up"),
1181
- // Sign In Link
1182
- props.showSignIn && vue.h("div", { "data-authos-signin-prompt": "" }, [
1183
- "Already have an account? ",
1184
- vue.h("a", { href: "/signin", "data-authos-link": "signin" }, "Sign in")
1185
- ])
1186
- ])
1187
- ]);
1188
- };
1189
- }
1038
+ //#endregion
1039
+ //#region src/components/SignUp.ts
1040
+ const SignUp = (0, vue.defineComponent)({
1041
+ name: "SignUp",
1042
+ props: {
1043
+ onSuccess: {
1044
+ type: Function,
1045
+ default: void 0
1046
+ },
1047
+ onError: {
1048
+ type: Function,
1049
+ default: void 0
1050
+ },
1051
+ /** Organization slug for tenant context */
1052
+ orgSlug: {
1053
+ type: String,
1054
+ default: void 0
1055
+ },
1056
+ /** Service slug for tenant attribution (used with orgSlug) */
1057
+ serviceSlug: {
1058
+ type: String,
1059
+ default: void 0
1060
+ },
1061
+ /** List of OAuth providers to display buttons for */
1062
+ providers: {
1063
+ type: [Array, Boolean],
1064
+ default: false
1065
+ },
1066
+ /** Show divider between OAuth and email form */
1067
+ showDivider: {
1068
+ type: Boolean,
1069
+ default: true
1070
+ },
1071
+ /** Show sign in link */
1072
+ showSignIn: {
1073
+ type: Boolean,
1074
+ default: true
1075
+ }
1076
+ },
1077
+ emits: ["success", "error"],
1078
+ setup(props, { slots, emit }) {
1079
+ const { client, options } = require_useAuthOS.useAuthOS();
1080
+ const email = (0, vue.ref)("");
1081
+ const password = (0, vue.ref)("");
1082
+ const confirmPassword = (0, vue.ref)("");
1083
+ const error = (0, vue.ref)(null);
1084
+ const isSubmitting = (0, vue.ref)(false);
1085
+ const isSuccess = (0, vue.ref)(false);
1086
+ const hasOAuthConfig = !!(options.org && options.service);
1087
+ const oauthProviders = Array.isArray(props.providers) ? props.providers : [];
1088
+ async function submit() {
1089
+ error.value = null;
1090
+ if (password.value !== confirmPassword.value) {
1091
+ error.value = "Passwords do not match";
1092
+ return;
1093
+ }
1094
+ if (password.value.length < 8) {
1095
+ error.value = "Password must be at least 8 characters";
1096
+ return;
1097
+ }
1098
+ isSubmitting.value = true;
1099
+ try {
1100
+ await client.auth.register({
1101
+ email: email.value,
1102
+ password: password.value,
1103
+ org_slug: props.orgSlug ?? options.org,
1104
+ service_slug: props.serviceSlug ?? options.service
1105
+ });
1106
+ isSuccess.value = true;
1107
+ emit("success");
1108
+ props.onSuccess?.();
1109
+ } catch (err) {
1110
+ const message = err instanceof _drmhse_sso_sdk.SsoApiError ? err.message : "Registration failed";
1111
+ error.value = message;
1112
+ const e = err instanceof Error ? err : new Error(message);
1113
+ emit("error", e);
1114
+ props.onError?.(e);
1115
+ } finally {
1116
+ isSubmitting.value = false;
1117
+ }
1118
+ }
1119
+ return () => {
1120
+ const slotProps = {
1121
+ email: email.value,
1122
+ password: password.value,
1123
+ error: error.value,
1124
+ isSubmitting: isSubmitting.value,
1125
+ updateEmail: (v) => email.value = v,
1126
+ updatePassword: (v) => password.value = v,
1127
+ submit
1128
+ };
1129
+ if (slots.default) return slots.default(slotProps);
1130
+ if (isSuccess.value) return (0, vue.h)("div", {
1131
+ "data-authos-signup": "",
1132
+ "data-state": "success"
1133
+ }, [(0, vue.h)("div", { "data-authos-success": "" }, [(0, vue.h)("h2", "Check your email"), (0, vue.h)("p", `We've sent a verification link to ${email.value}. Please click the link to verify your account.`)])]);
1134
+ return (0, vue.h)("div", {
1135
+ "data-authos-signup": "",
1136
+ "data-state": "credentials"
1137
+ }, [
1138
+ oauthProviders.length > 0 && (0, vue.h)("div", { "data-authos-oauth-section": "" }, [oauthProviders.map((provider) => (0, vue.h)(OAuthButton, {
1139
+ key: provider,
1140
+ provider,
1141
+ disabled: isSubmitting.value || !hasOAuthConfig
1142
+ })), !hasOAuthConfig && (0, vue.h)("p", {
1143
+ "data-authos-oauth-warning": "",
1144
+ style: {
1145
+ color: "orange",
1146
+ fontSize: "0.875rem"
1147
+ }
1148
+ }, "OAuth requires org and service in plugin options")]),
1149
+ oauthProviders.length > 0 && props.showDivider && (0, vue.h)("div", { "data-authos-divider": "" }, [(0, vue.h)("span", "or")]),
1150
+ (0, vue.h)("form", { onSubmit: (e) => {
1151
+ e.preventDefault();
1152
+ submit();
1153
+ } }, [
1154
+ (0, vue.h)("div", { "data-authos-field": "email" }, [(0, vue.h)("label", { for: "authos-signup-email" }, "Email"), (0, vue.h)("input", {
1155
+ id: "authos-signup-email",
1156
+ type: "email",
1157
+ autocomplete: "email",
1158
+ value: email.value,
1159
+ placeholder: "Enter your email",
1160
+ required: true,
1161
+ disabled: isSubmitting.value,
1162
+ onInput: (e) => email.value = e.target.value
1163
+ })]),
1164
+ (0, vue.h)("div", { "data-authos-field": "password" }, [(0, vue.h)("label", { for: "authos-signup-password" }, "Password"), (0, vue.h)("input", {
1165
+ id: "authos-signup-password",
1166
+ type: "password",
1167
+ autocomplete: "new-password",
1168
+ value: password.value,
1169
+ placeholder: "Create a password",
1170
+ required: true,
1171
+ disabled: isSubmitting.value,
1172
+ onInput: (e) => password.value = e.target.value
1173
+ })]),
1174
+ (0, vue.h)("div", { "data-authos-field": "confirm-password" }, [(0, vue.h)("label", { for: "authos-signup-confirm" }, "Confirm Password"), (0, vue.h)("input", {
1175
+ id: "authos-signup-confirm",
1176
+ type: "password",
1177
+ autocomplete: "new-password",
1178
+ value: confirmPassword.value,
1179
+ placeholder: "Confirm your password",
1180
+ required: true,
1181
+ disabled: isSubmitting.value,
1182
+ onInput: (e) => confirmPassword.value = e.target.value
1183
+ })]),
1184
+ error.value && (0, vue.h)("div", { "data-authos-error": "" }, error.value),
1185
+ (0, vue.h)("button", {
1186
+ type: "submit",
1187
+ disabled: isSubmitting.value,
1188
+ "data-authos-submit": ""
1189
+ }, isSubmitting.value ? "Creating account..." : "Sign Up"),
1190
+ props.showSignIn && (0, vue.h)("div", { "data-authos-signin-prompt": "" }, ["Already have an account? ", (0, vue.h)("a", {
1191
+ href: "/signin",
1192
+ "data-authos-link": "signin"
1193
+ }, "Sign in")])
1194
+ ])
1195
+ ]);
1196
+ };
1197
+ }
1190
1198
  });
1191
- var OrganizationSwitcher = vue.defineComponent({
1192
- name: "OrganizationSwitcher",
1193
- props: {
1194
- onSwitch: {
1195
- type: Function,
1196
- default: void 0
1197
- }
1198
- },
1199
- emits: ["switch"],
1200
- setup(props, { slots, emit }) {
1201
- const { currentOrganization, organizations, switchOrganization, isSwitching } = useOrganization();
1202
- async function switchTo(slug) {
1203
- await switchOrganization(slug);
1204
- const org = organizations.value.find((o) => o.organization.slug === slug);
1205
- if (org) {
1206
- emit("switch", org);
1207
- props.onSwitch?.(org);
1208
- }
1209
- }
1210
- return () => {
1211
- const slotProps = {
1212
- currentOrganization: currentOrganization.value,
1213
- organizations: organizations.value,
1214
- isSwitching: isSwitching.value,
1215
- switchTo
1216
- };
1217
- if (slots.default) {
1218
- return slots.default(slotProps);
1219
- }
1220
- return vue.h(
1221
- "div",
1222
- { "data-authos-orgswitcher": "", "data-state": organizations.value.length > 0 ? "ready" : "empty" },
1223
- organizations.value.length > 0 ? vue.h(
1224
- "select",
1225
- {
1226
- value: currentOrganization.value?.organization.slug ?? "",
1227
- disabled: isSwitching.value,
1228
- onChange: (e) => switchTo(e.target.value)
1229
- },
1230
- organizations.value.map(
1231
- (org) => vue.h("option", { key: org.organization.id, value: org.organization.slug }, org.organization.name)
1232
- )
1233
- ) : "No organizations"
1234
- );
1235
- };
1236
- }
1199
+ //#endregion
1200
+ //#region src/components/OrganizationSwitcher.ts
1201
+ const OrganizationSwitcher = (0, vue.defineComponent)({
1202
+ name: "OrganizationSwitcher",
1203
+ props: { onSwitch: {
1204
+ type: Function,
1205
+ default: void 0
1206
+ } },
1207
+ emits: ["switch"],
1208
+ setup(props, { slots, emit }) {
1209
+ const { currentOrganization, organizations, switchOrganization, isSwitching } = useOrganization();
1210
+ async function switchTo(slug) {
1211
+ await switchOrganization(slug);
1212
+ const org = organizations.value.find((o) => o.organization.slug === slug);
1213
+ if (org) {
1214
+ emit("switch", org);
1215
+ props.onSwitch?.(org);
1216
+ }
1217
+ }
1218
+ return () => {
1219
+ const slotProps = {
1220
+ currentOrganization: currentOrganization.value,
1221
+ organizations: organizations.value,
1222
+ isSwitching: isSwitching.value,
1223
+ switchTo
1224
+ };
1225
+ if (slots.default) return slots.default(slotProps);
1226
+ return (0, vue.h)("div", {
1227
+ "data-authos-orgswitcher": "",
1228
+ "data-state": organizations.value.length > 0 ? "ready" : "empty"
1229
+ }, organizations.value.length > 0 ? (0, vue.h)("select", {
1230
+ value: currentOrganization.value?.organization.slug ?? "",
1231
+ disabled: isSwitching.value,
1232
+ onChange: (e) => switchTo(e.target.value)
1233
+ }, organizations.value.map((org) => (0, vue.h)("option", {
1234
+ key: org.organization.id,
1235
+ value: org.organization.slug
1236
+ }, org.organization.name))) : "No organizations");
1237
+ };
1238
+ }
1237
1239
  });
1238
- var UserButton = vue.defineComponent({
1239
- name: "UserButton",
1240
- props: {
1241
- onLogout: {
1242
- type: Function,
1243
- default: void 0
1244
- }
1245
- },
1246
- emits: ["logout"],
1247
- setup(props, { slots, emit }) {
1248
- const { user, isLoading } = useUser();
1249
- const { client } = useAuthOS();
1250
- const isLoggingOut = vue.ref(false);
1251
- async function logout() {
1252
- isLoggingOut.value = true;
1253
- try {
1254
- await client.auth.logout();
1255
- emit("logout");
1256
- props.onLogout?.();
1257
- } finally {
1258
- isLoggingOut.value = false;
1259
- }
1260
- }
1261
- return () => {
1262
- const slotProps = {
1263
- user: user.value,
1264
- isLoading: isLoading.value,
1265
- isLoggingOut: isLoggingOut.value,
1266
- logout
1267
- };
1268
- if (slots.default) {
1269
- return slots.default(slotProps);
1270
- }
1271
- if (isLoading.value) {
1272
- return vue.h("div", { "data-authos-userbutton": "", "data-state": "loading" }, "Loading...");
1273
- }
1274
- if (!user.value) {
1275
- return vue.h("div", { "data-authos-userbutton": "", "data-state": "signed-out" }, "Not signed in");
1276
- }
1277
- const getInitials = (email) => {
1278
- const name = email.split("@")[0];
1279
- return name.substring(0, 2).toUpperCase();
1280
- };
1281
- return vue.h("div", { "data-authos-userbutton": "", "data-state": "signed-in" }, [
1282
- vue.h("div", { "data-authos-avatar": "" }, getInitials(user.value.email)),
1283
- vue.h("span", { "data-authos-email": "" }, user.value.email),
1284
- vue.h(
1285
- "button",
1286
- {
1287
- "data-authos-logout": "",
1288
- onClick: logout,
1289
- disabled: isLoggingOut.value
1290
- },
1291
- isLoggingOut.value ? "Logging out..." : "Logout"
1292
- )
1293
- ]);
1294
- };
1295
- }
1240
+ //#endregion
1241
+ //#region src/components/UserButton.ts
1242
+ const UserButton = (0, vue.defineComponent)({
1243
+ name: "UserButton",
1244
+ props: { onLogout: {
1245
+ type: Function,
1246
+ default: void 0
1247
+ } },
1248
+ emits: ["logout"],
1249
+ setup(props, { slots, emit }) {
1250
+ const { user, isLoading } = useUser();
1251
+ const { client } = require_useAuthOS.useAuthOS();
1252
+ const isLoggingOut = (0, vue.ref)(false);
1253
+ async function logout() {
1254
+ isLoggingOut.value = true;
1255
+ try {
1256
+ await client.auth.logout();
1257
+ emit("logout");
1258
+ props.onLogout?.();
1259
+ } finally {
1260
+ isLoggingOut.value = false;
1261
+ }
1262
+ }
1263
+ return () => {
1264
+ const slotProps = {
1265
+ user: user.value,
1266
+ isLoading: isLoading.value,
1267
+ isLoggingOut: isLoggingOut.value,
1268
+ logout
1269
+ };
1270
+ if (slots.default) return slots.default(slotProps);
1271
+ if (isLoading.value) return (0, vue.h)("div", {
1272
+ "data-authos-userbutton": "",
1273
+ "data-state": "loading"
1274
+ }, "Loading...");
1275
+ if (!user.value) return (0, vue.h)("div", {
1276
+ "data-authos-userbutton": "",
1277
+ "data-state": "signed-out"
1278
+ }, "Not signed in");
1279
+ const getInitials = (email) => {
1280
+ return email.split("@")[0].substring(0, 2).toUpperCase();
1281
+ };
1282
+ return (0, vue.h)("div", {
1283
+ "data-authos-userbutton": "",
1284
+ "data-state": "signed-in"
1285
+ }, [
1286
+ (0, vue.h)("div", { "data-authos-avatar": "" }, getInitials(user.value.email)),
1287
+ (0, vue.h)("span", { "data-authos-email": "" }, user.value.email),
1288
+ (0, vue.h)("button", {
1289
+ "data-authos-logout": "",
1290
+ onClick: logout,
1291
+ disabled: isLoggingOut.value
1292
+ }, isLoggingOut.value ? "Logging out..." : "Logout")
1293
+ ]);
1294
+ };
1295
+ }
1296
1296
  });
1297
- var Protect = vue.defineComponent({
1298
- name: "Protect",
1299
- props: {
1300
- permission: {
1301
- type: String,
1302
- default: void 0
1303
- },
1304
- permissions: {
1305
- type: Array,
1306
- default: void 0
1307
- },
1308
- requireAll: {
1309
- type: Boolean,
1310
- default: false
1311
- },
1312
- fallback: {
1313
- type: [Object, Function],
1314
- default: void 0
1315
- }
1316
- },
1317
- setup(props, { slots }) {
1318
- const { user, isLoading } = useUser();
1319
- const hasAccess = vue.computed(() => {
1320
- if (isLoading.value || !user.value) {
1321
- return false;
1322
- }
1323
- const userPermissions = user.value.permissions ?? [];
1324
- if (props.permission) {
1325
- return userPermissions.includes(props.permission);
1326
- }
1327
- if (props.permissions && props.permissions.length > 0) {
1328
- if (props.requireAll) {
1329
- return props.permissions.every((p) => userPermissions.includes(p));
1330
- }
1331
- return props.permissions.some((p) => userPermissions.includes(p));
1332
- }
1333
- return true;
1334
- });
1335
- return () => {
1336
- if (isLoading.value) {
1337
- return vue.h("div", { "data-authos-protect": "", "data-state": "loading" });
1338
- }
1339
- if (hasAccess.value) {
1340
- return vue.h("div", { "data-authos-protect": "", "data-state": "allowed" }, slots.default?.());
1341
- }
1342
- if (props.fallback) {
1343
- const fallbackContent = typeof props.fallback === "function" ? props.fallback() : props.fallback;
1344
- return vue.h("div", { "data-authos-protect": "", "data-state": "denied" }, [fallbackContent]);
1345
- }
1346
- if (slots.fallback) {
1347
- return vue.h("div", { "data-authos-protect": "", "data-state": "denied" }, slots.fallback());
1348
- }
1349
- return vue.h("div", { "data-authos-protect": "", "data-state": "denied" });
1350
- };
1351
- }
1297
+ //#endregion
1298
+ //#region src/components/Protect.ts
1299
+ const Protect = (0, vue.defineComponent)({
1300
+ name: "Protect",
1301
+ props: {
1302
+ permission: {
1303
+ type: String,
1304
+ default: void 0
1305
+ },
1306
+ permissions: {
1307
+ type: Array,
1308
+ default: void 0
1309
+ },
1310
+ requireAll: {
1311
+ type: Boolean,
1312
+ default: false
1313
+ },
1314
+ fallback: {
1315
+ type: [Object, Function],
1316
+ default: void 0
1317
+ }
1318
+ },
1319
+ setup(props, { slots }) {
1320
+ const { user, isLoading } = useUser();
1321
+ const hasAccess = (0, vue.computed)(() => {
1322
+ if (isLoading.value || !user.value) return false;
1323
+ const userPermissions = user.value.permissions ?? [];
1324
+ if (props.permission) return userPermissions.includes(props.permission);
1325
+ if (props.permissions && props.permissions.length > 0) {
1326
+ if (props.requireAll) return props.permissions.every((p) => userPermissions.includes(p));
1327
+ return props.permissions.some((p) => userPermissions.includes(p));
1328
+ }
1329
+ return true;
1330
+ });
1331
+ return () => {
1332
+ if (isLoading.value) return (0, vue.h)("div", {
1333
+ "data-authos-protect": "",
1334
+ "data-state": "loading"
1335
+ });
1336
+ if (hasAccess.value) return (0, vue.h)("div", {
1337
+ "data-authos-protect": "",
1338
+ "data-state": "allowed"
1339
+ }, slots.default?.());
1340
+ if (props.fallback) return (0, vue.h)("div", {
1341
+ "data-authos-protect": "",
1342
+ "data-state": "denied"
1343
+ }, [typeof props.fallback === "function" ? props.fallback() : props.fallback]);
1344
+ if (slots.fallback) return (0, vue.h)("div", {
1345
+ "data-authos-protect": "",
1346
+ "data-state": "denied"
1347
+ }, slots.fallback());
1348
+ return (0, vue.h)("div", {
1349
+ "data-authos-protect": "",
1350
+ "data-state": "denied"
1351
+ });
1352
+ };
1353
+ }
1352
1354
  });
1353
- var SignedIn = vue.defineComponent({
1354
- name: "SignedIn",
1355
- setup(_, { slots }) {
1356
- const { isAuthenticated, isLoading } = useAuthOS();
1357
- return () => {
1358
- if (isLoading.value) {
1359
- return null;
1360
- }
1361
- if (!isAuthenticated.value) {
1362
- return null;
1363
- }
1364
- return slots.default?.();
1365
- };
1366
- }
1355
+ //#endregion
1356
+ //#region src/components/SignedIn.ts
1357
+ /**
1358
+ * Renders children only when the user is authenticated.
1359
+ * Use with SignedOut to create conditional UI based on auth state.
1360
+ *
1361
+ * @example
1362
+ * ```vue
1363
+ * <script setup>
1364
+ * import { SignedIn, SignedOut, UserButton, SignIn } from '@drmhse/authos-vue';
1365
+ * <\/script>
1366
+ *
1367
+ * <template>
1368
+ * <header>
1369
+ * <SignedIn>
1370
+ * <UserButton />
1371
+ * </SignedIn>
1372
+ * <SignedOut>
1373
+ * <SignIn />
1374
+ * </SignedOut>
1375
+ * </header>
1376
+ * </template>
1377
+ * ```
1378
+ */
1379
+ const SignedIn = (0, vue.defineComponent)({
1380
+ name: "SignedIn",
1381
+ setup(_, { slots }) {
1382
+ const { isAuthenticated, isLoading } = require_useAuthOS.useAuthOS();
1383
+ return () => {
1384
+ if (isLoading.value) return null;
1385
+ if (!isAuthenticated.value) return null;
1386
+ return slots.default?.();
1387
+ };
1388
+ }
1367
1389
  });
1368
- var SignedOut = vue.defineComponent({
1369
- name: "SignedOut",
1370
- setup(_, { slots }) {
1371
- const { isAuthenticated, isLoading } = useAuthOS();
1372
- return () => {
1373
- if (isLoading.value) {
1374
- return null;
1375
- }
1376
- if (isAuthenticated.value) {
1377
- return null;
1378
- }
1379
- return slots.default?.();
1380
- };
1381
- }
1390
+ //#endregion
1391
+ //#region src/components/SignedOut.ts
1392
+ /**
1393
+ * Renders children only when the user is NOT authenticated.
1394
+ * Use with SignedIn to create conditional UI based on auth state.
1395
+ *
1396
+ * @example
1397
+ * ```vue
1398
+ * <script setup>
1399
+ * import { SignedIn, SignedOut, UserButton, SignIn } from '@drmhse/authos-vue';
1400
+ * <\/script>
1401
+ *
1402
+ * <template>
1403
+ * <header>
1404
+ * <SignedIn>
1405
+ * <UserButton />
1406
+ * </SignedIn>
1407
+ * <SignedOut>
1408
+ * <SignIn />
1409
+ * </SignedOut>
1410
+ * </header>
1411
+ * </template>
1412
+ * ```
1413
+ */
1414
+ const SignedOut = (0, vue.defineComponent)({
1415
+ name: "SignedOut",
1416
+ setup(_, { slots }) {
1417
+ const { isAuthenticated, isLoading } = require_useAuthOS.useAuthOS();
1418
+ return () => {
1419
+ if (isLoading.value) return null;
1420
+ if (isAuthenticated.value) return null;
1421
+ return slots.default?.();
1422
+ };
1423
+ }
1382
1424
  });
1383
- var MagicLinkSignIn = vue.defineComponent({
1384
- name: "MagicLinkSignIn",
1385
- props: {
1386
- showPasswordSignIn: {
1387
- type: Boolean,
1388
- default: true
1389
- }
1390
- },
1391
- emits: ["success", "error"],
1392
- setup(props, { emit, slots }) {
1393
- const { client } = useAuthOS();
1394
- const email = vue.ref("");
1395
- const isLoading = vue.ref(false);
1396
- const error = vue.ref(null);
1397
- const isSent = vue.ref(false);
1398
- async function handleSubmit() {
1399
- error.value = null;
1400
- isLoading.value = true;
1401
- try {
1402
- await client.magicLinks.request({ email: email.value });
1403
- isSent.value = true;
1404
- emit("success");
1405
- } catch (err) {
1406
- const message = err instanceof Error ? err.message : "Failed to send magic link";
1407
- error.value = message;
1408
- emit("error", err);
1409
- } finally {
1410
- isLoading.value = false;
1411
- }
1412
- }
1413
- const slotProps = vue.computed(() => ({
1414
- email: email.value,
1415
- isLoading: isLoading.value,
1416
- error: error.value,
1417
- isSent: isSent.value,
1418
- updateEmail: (val) => {
1419
- email.value = val;
1420
- },
1421
- submit: handleSubmit,
1422
- reset: () => {
1423
- isSent.value = false;
1424
- }
1425
- }));
1426
- return () => {
1427
- if (slots.default) {
1428
- return slots.default(slotProps.value);
1429
- }
1430
- if (isSent.value) {
1431
- return vue.h("div", { "data-authos-magic-link": "", "data-state": "sent" }, [
1432
- vue.h("div", { "data-authos-success": "" }, [
1433
- vue.h("p", "Check your email!"),
1434
- vue.h("p", ["We sent a login link to ", vue.h("strong", email.value)])
1435
- ]),
1436
- vue.h("button", {
1437
- type: "button",
1438
- onClick: () => {
1439
- isSent.value = false;
1440
- },
1441
- "data-authos-back": ""
1442
- }, "Use a different email")
1443
- ]);
1444
- }
1445
- return vue.h("form", {
1446
- onSubmit: (e) => {
1447
- e.preventDefault();
1448
- handleSubmit();
1449
- },
1450
- "data-authos-magic-link": "",
1451
- "data-state": "form"
1452
- }, [
1453
- vue.h("div", { "data-authos-field": "email" }, [
1454
- vue.h("label", { for: "authos-magic-email" }, "Email"),
1455
- vue.h("input", {
1456
- id: "authos-magic-email",
1457
- type: "email",
1458
- autocomplete: "email",
1459
- value: email.value,
1460
- onInput: (e) => {
1461
- email.value = e.target.value;
1462
- },
1463
- placeholder: "Enter your email",
1464
- required: true,
1465
- disabled: isLoading.value
1466
- })
1467
- ]),
1468
- error.value ? vue.h("div", { "data-authos-error": "" }, error.value) : null,
1469
- vue.h("button", {
1470
- type: "submit",
1471
- disabled: isLoading.value,
1472
- "data-authos-submit": ""
1473
- }, isLoading.value ? "Sending..." : "Send Magic Link"),
1474
- props.showPasswordSignIn ? vue.h("div", { "data-authos-signin-prompt": "" }, [
1475
- vue.h("a", { href: "/signin", "data-authos-link": "signin" }, "Sign in with password")
1476
- ]) : null
1477
- ]);
1478
- };
1479
- }
1425
+ //#endregion
1426
+ //#region src/components/MagicLinkSignIn.ts
1427
+ /**
1428
+ * Passwordless sign-in via magic link (email).
1429
+ *
1430
+ * Sends a one-time login link to the user's email address.
1431
+ *
1432
+ * @example
1433
+ * ```vue
1434
+ * <script setup>
1435
+ * import { MagicLinkSignIn } from '@drmhse/authos-vue';
1436
+ * <\/script>
1437
+ *
1438
+ * <template>
1439
+ * <MagicLinkSignIn @success="() => alert('Check your email!')" />
1440
+ * </template>
1441
+ * ```
1442
+ */
1443
+ const MagicLinkSignIn = (0, vue.defineComponent)({
1444
+ name: "MagicLinkSignIn",
1445
+ props: { showPasswordSignIn: {
1446
+ type: Boolean,
1447
+ default: true
1448
+ } },
1449
+ emits: ["success", "error"],
1450
+ setup(props, { emit, slots }) {
1451
+ const { client } = require_useAuthOS.useAuthOS();
1452
+ const email = (0, vue.ref)("");
1453
+ const isLoading = (0, vue.ref)(false);
1454
+ const error = (0, vue.ref)(null);
1455
+ const isSent = (0, vue.ref)(false);
1456
+ async function handleSubmit() {
1457
+ error.value = null;
1458
+ isLoading.value = true;
1459
+ try {
1460
+ await client.magicLinks.request({ email: email.value });
1461
+ isSent.value = true;
1462
+ emit("success");
1463
+ } catch (err) {
1464
+ error.value = err instanceof Error ? err.message : "Failed to send magic link";
1465
+ emit("error", err);
1466
+ } finally {
1467
+ isLoading.value = false;
1468
+ }
1469
+ }
1470
+ const slotProps = (0, vue.computed)(() => ({
1471
+ email: email.value,
1472
+ isLoading: isLoading.value,
1473
+ error: error.value,
1474
+ isSent: isSent.value,
1475
+ updateEmail: (val) => {
1476
+ email.value = val;
1477
+ },
1478
+ submit: handleSubmit,
1479
+ reset: () => {
1480
+ isSent.value = false;
1481
+ }
1482
+ }));
1483
+ return () => {
1484
+ if (slots.default) return slots.default(slotProps.value);
1485
+ if (isSent.value) return (0, vue.h)("div", {
1486
+ "data-authos-magic-link": "",
1487
+ "data-state": "sent"
1488
+ }, [(0, vue.h)("div", { "data-authos-success": "" }, [(0, vue.h)("p", "Check your email!"), (0, vue.h)("p", ["We sent a login link to ", (0, vue.h)("strong", email.value)])]), (0, vue.h)("button", {
1489
+ type: "button",
1490
+ onClick: () => {
1491
+ isSent.value = false;
1492
+ },
1493
+ "data-authos-back": ""
1494
+ }, "Use a different email")]);
1495
+ return (0, vue.h)("form", {
1496
+ onSubmit: (e) => {
1497
+ e.preventDefault();
1498
+ handleSubmit();
1499
+ },
1500
+ "data-authos-magic-link": "",
1501
+ "data-state": "form"
1502
+ }, [
1503
+ (0, vue.h)("div", { "data-authos-field": "email" }, [(0, vue.h)("label", { for: "authos-magic-email" }, "Email"), (0, vue.h)("input", {
1504
+ id: "authos-magic-email",
1505
+ type: "email",
1506
+ autocomplete: "email",
1507
+ value: email.value,
1508
+ onInput: (e) => {
1509
+ email.value = e.target.value;
1510
+ },
1511
+ placeholder: "Enter your email",
1512
+ required: true,
1513
+ disabled: isLoading.value
1514
+ })]),
1515
+ error.value ? (0, vue.h)("div", { "data-authos-error": "" }, error.value) : null,
1516
+ (0, vue.h)("button", {
1517
+ type: "submit",
1518
+ disabled: isLoading.value,
1519
+ "data-authos-submit": ""
1520
+ }, isLoading.value ? "Sending..." : "Send Magic Link"),
1521
+ props.showPasswordSignIn ? (0, vue.h)("div", { "data-authos-signin-prompt": "" }, [(0, vue.h)("a", {
1522
+ href: "/signin",
1523
+ "data-authos-link": "signin"
1524
+ }, "Sign in with password")]) : null
1525
+ ]);
1526
+ };
1527
+ }
1480
1528
  });
1481
- var PasskeySignIn = vue.defineComponent({
1482
- name: "PasskeySignIn",
1483
- props: {
1484
- showPasswordSignIn: {
1485
- type: Boolean,
1486
- default: true
1487
- },
1488
- orgSlug: {
1489
- type: String,
1490
- default: void 0
1491
- },
1492
- serviceSlug: {
1493
- type: String,
1494
- default: void 0
1495
- },
1496
- redirectUri: {
1497
- type: String,
1498
- default: void 0
1499
- },
1500
- state: {
1501
- type: String,
1502
- default: void 0
1503
- }
1504
- },
1505
- emits: ["success", "error"],
1506
- setup(props, { emit, slots }) {
1507
- const { client, options } = useAuthOS();
1508
- const email = vue.ref("");
1509
- const isLoading = vue.ref(false);
1510
- const error = vue.ref(null);
1511
- const isSupported = vue.ref(true);
1512
- vue.onMounted(() => {
1513
- isSupported.value = client.passkeys.isSupported();
1514
- });
1515
- async function handleSubmit() {
1516
- error.value = null;
1517
- isLoading.value = true;
1518
- try {
1519
- const org = props.orgSlug ?? options.org;
1520
- const service = props.serviceSlug ?? options.service;
1521
- const passkeyContext = org && service ? {
1522
- org_slug: org,
1523
- service_slug: service,
1524
- redirect_uri: props.redirectUri ?? options.redirectUri,
1525
- state: props.state
1526
- } : void 0;
1527
- await client.passkeys.login(email.value, passkeyContext);
1528
- emit("success");
1529
- } catch (err) {
1530
- const message = err instanceof Error ? err.message : "Passkey authentication failed";
1531
- error.value = message;
1532
- emit("error", err);
1533
- } finally {
1534
- isLoading.value = false;
1535
- }
1536
- }
1537
- const slotProps = vue.computed(() => ({
1538
- email: email.value,
1539
- isLoading: isLoading.value,
1540
- error: error.value,
1541
- isSupported: isSupported.value,
1542
- updateEmail: (val) => {
1543
- email.value = val;
1544
- },
1545
- submit: handleSubmit
1546
- }));
1547
- return () => {
1548
- if (slots.default) {
1549
- return slots.default(slotProps.value);
1550
- }
1551
- if (!isSupported.value) {
1552
- return vue.h("div", {
1553
- "data-authos-passkey": "",
1554
- "data-state": "unsupported"
1555
- }, [
1556
- vue.h("div", { "data-authos-error": "" }, "Passkeys are not supported in this browser."),
1557
- props.showPasswordSignIn ? vue.h("a", { href: "/signin", "data-authos-link": "signin" }, "Sign in with password") : null
1558
- ]);
1559
- }
1560
- return vue.h("form", {
1561
- onSubmit: (e) => {
1562
- e.preventDefault();
1563
- handleSubmit();
1564
- },
1565
- "data-authos-passkey": ""
1566
- }, [
1567
- vue.h("div", { "data-authos-field": "email" }, [
1568
- vue.h("label", { for: "authos-passkey-email" }, "Email"),
1569
- vue.h("input", {
1570
- id: "authos-passkey-email",
1571
- type: "email",
1572
- autocomplete: "email webauthn",
1573
- value: email.value,
1574
- onInput: (e) => {
1575
- email.value = e.target.value;
1576
- },
1577
- placeholder: "Enter your email",
1578
- required: true,
1579
- disabled: isLoading.value
1580
- })
1581
- ]),
1582
- error.value ? vue.h("div", { "data-authos-error": "" }, error.value) : null,
1583
- vue.h("button", {
1584
- type: "submit",
1585
- disabled: isLoading.value,
1586
- "data-authos-submit": ""
1587
- }, isLoading.value ? "Authenticating..." : "Sign in with Passkey"),
1588
- props.showPasswordSignIn ? vue.h("div", { "data-authos-signin-prompt": "" }, [
1589
- vue.h("a", { href: "/signin", "data-authos-link": "signin" }, "Sign in with password")
1590
- ]) : null
1591
- ]);
1592
- };
1593
- }
1529
+ //#endregion
1530
+ //#region src/components/PasskeySignIn.ts
1531
+ /**
1532
+ * Passkey (WebAuthn) sign-in component.
1533
+ *
1534
+ * Uses the Web Authentication API for passwordless authentication
1535
+ * via biometrics, security keys, or platform authenticators.
1536
+ *
1537
+ * @example
1538
+ * ```vue
1539
+ * <script setup>
1540
+ * import { PasskeySignIn } from '@drmhse/authos-vue';
1541
+ * <\/script>
1542
+ *
1543
+ * <template>
1544
+ * <PasskeySignIn @success="() => router.push('/dashboard')" />
1545
+ * </template>
1546
+ * ```
1547
+ */
1548
+ const PasskeySignIn = (0, vue.defineComponent)({
1549
+ name: "PasskeySignIn",
1550
+ props: {
1551
+ showPasswordSignIn: {
1552
+ type: Boolean,
1553
+ default: true
1554
+ },
1555
+ orgSlug: {
1556
+ type: String,
1557
+ default: void 0
1558
+ },
1559
+ serviceSlug: {
1560
+ type: String,
1561
+ default: void 0
1562
+ },
1563
+ redirectUri: {
1564
+ type: String,
1565
+ default: void 0
1566
+ },
1567
+ state: {
1568
+ type: String,
1569
+ default: void 0
1570
+ }
1571
+ },
1572
+ emits: ["success", "error"],
1573
+ setup(props, { emit, slots }) {
1574
+ const { client, options } = require_useAuthOS.useAuthOS();
1575
+ const email = (0, vue.ref)("");
1576
+ const isLoading = (0, vue.ref)(false);
1577
+ const error = (0, vue.ref)(null);
1578
+ const isSupported = (0, vue.ref)(true);
1579
+ (0, vue.onMounted)(() => {
1580
+ isSupported.value = client.passkeys.isSupported();
1581
+ });
1582
+ async function handleSubmit() {
1583
+ error.value = null;
1584
+ isLoading.value = true;
1585
+ try {
1586
+ const org = props.orgSlug ?? options.org;
1587
+ const service = props.serviceSlug ?? options.service;
1588
+ const passkeyContext = org && service ? {
1589
+ org_slug: org,
1590
+ service_slug: service,
1591
+ redirect_uri: props.redirectUri ?? options.redirectUri,
1592
+ state: props.state
1593
+ } : void 0;
1594
+ await client.passkeys.login(email.value, passkeyContext);
1595
+ emit("success");
1596
+ } catch (err) {
1597
+ error.value = err instanceof Error ? err.message : "Passkey authentication failed";
1598
+ emit("error", err);
1599
+ } finally {
1600
+ isLoading.value = false;
1601
+ }
1602
+ }
1603
+ const slotProps = (0, vue.computed)(() => ({
1604
+ email: email.value,
1605
+ isLoading: isLoading.value,
1606
+ error: error.value,
1607
+ isSupported: isSupported.value,
1608
+ updateEmail: (val) => {
1609
+ email.value = val;
1610
+ },
1611
+ submit: handleSubmit
1612
+ }));
1613
+ return () => {
1614
+ if (slots.default) return slots.default(slotProps.value);
1615
+ if (!isSupported.value) return (0, vue.h)("div", {
1616
+ "data-authos-passkey": "",
1617
+ "data-state": "unsupported"
1618
+ }, [(0, vue.h)("div", { "data-authos-error": "" }, "Passkeys are not supported in this browser."), props.showPasswordSignIn ? (0, vue.h)("a", {
1619
+ href: "/signin",
1620
+ "data-authos-link": "signin"
1621
+ }, "Sign in with password") : null]);
1622
+ return (0, vue.h)("form", {
1623
+ onSubmit: (e) => {
1624
+ e.preventDefault();
1625
+ handleSubmit();
1626
+ },
1627
+ "data-authos-passkey": ""
1628
+ }, [
1629
+ (0, vue.h)("div", { "data-authos-field": "email" }, [(0, vue.h)("label", { for: "authos-passkey-email" }, "Email"), (0, vue.h)("input", {
1630
+ id: "authos-passkey-email",
1631
+ type: "email",
1632
+ autocomplete: "email webauthn",
1633
+ value: email.value,
1634
+ onInput: (e) => {
1635
+ email.value = e.target.value;
1636
+ },
1637
+ placeholder: "Enter your email",
1638
+ required: true,
1639
+ disabled: isLoading.value
1640
+ })]),
1641
+ error.value ? (0, vue.h)("div", { "data-authos-error": "" }, error.value) : null,
1642
+ (0, vue.h)("button", {
1643
+ type: "submit",
1644
+ disabled: isLoading.value,
1645
+ "data-authos-submit": ""
1646
+ }, isLoading.value ? "Authenticating..." : "Sign in with Passkey"),
1647
+ props.showPasswordSignIn ? (0, vue.h)("div", { "data-authos-signin-prompt": "" }, [(0, vue.h)("a", {
1648
+ href: "/signin",
1649
+ "data-authos-link": "signin"
1650
+ }, "Sign in with password")]) : null
1651
+ ]);
1652
+ };
1653
+ }
1594
1654
  });
1595
- var Callback = vue.defineComponent({
1596
- name: "Callback",
1597
- props: {
1598
- onSuccess: {
1599
- type: Function,
1600
- default: void 0
1601
- },
1602
- onError: {
1603
- type: Function,
1604
- default: void 0
1605
- }
1606
- },
1607
- emits: ["success", "error"],
1608
- setup(props, { slots, emit }) {
1609
- const { client } = useAuthOS();
1610
- const error = vue.ref(null);
1611
- vue.onMounted(async () => {
1612
- if (!client) {
1613
- error.value = "AuthOS client not initialized";
1614
- return;
1615
- }
1616
- const hashParams = new URLSearchParams(window.location.hash.substring(1));
1617
- const queryParams = new URLSearchParams(window.location.search);
1618
- const accessToken = hashParams.get("access_token") || queryParams.get("access_token");
1619
- const refreshToken = hashParams.get("refresh_token") || queryParams.get("refresh_token");
1620
- const errorParam = hashParams.get("error") || queryParams.get("error");
1621
- const errorDescription = hashParams.get("error_description") || queryParams.get("error_description");
1622
- if (errorParam) {
1623
- const msg = errorDescription || errorParam;
1624
- error.value = msg;
1625
- const e = new Error(msg);
1626
- emit("error", e);
1627
- props.onError?.(e);
1628
- return;
1629
- }
1630
- if (accessToken) {
1631
- try {
1632
- await client.setSession({
1633
- access_token: accessToken,
1634
- refresh_token: refreshToken || void 0
1635
- });
1636
- emit("success");
1637
- props.onSuccess?.();
1638
- } catch (err) {
1639
- const message = err.message || "Failed to set session";
1640
- error.value = message;
1641
- const e = err instanceof Error ? err : new Error(message);
1642
- emit("error", e);
1643
- props.onError?.(e);
1644
- }
1645
- } else {
1646
- const message = "No authentication tokens found in callback URL.";
1647
- error.value = message;
1648
- const e = new Error(message);
1649
- emit("error", e);
1650
- props.onError?.(e);
1651
- }
1652
- });
1653
- return () => {
1654
- const slotProps = {
1655
- error: error.value
1656
- };
1657
- if (slots.default) {
1658
- return slots.default(slotProps);
1659
- }
1660
- return vue.h("div", { "data-authos-callback": "" }, [
1661
- error.value ? vue.h("div", { "data-authos-error": "" }, error.value) : vue.h("div", { "data-authos-loading": "" }, "Completing sign in...")
1662
- ]);
1663
- };
1664
- }
1655
+ //#endregion
1656
+ //#region src/components/Callback.ts
1657
+ const Callback = (0, vue.defineComponent)({
1658
+ name: "Callback",
1659
+ props: {
1660
+ onSuccess: {
1661
+ type: Function,
1662
+ default: void 0
1663
+ },
1664
+ onError: {
1665
+ type: Function,
1666
+ default: void 0
1667
+ }
1668
+ },
1669
+ emits: ["success", "error"],
1670
+ setup(props, { slots, emit }) {
1671
+ const { client } = require_useAuthOS.useAuthOS();
1672
+ const error = (0, vue.ref)(null);
1673
+ (0, vue.onMounted)(async () => {
1674
+ if (!client) {
1675
+ error.value = "AuthOS client not initialized";
1676
+ return;
1677
+ }
1678
+ const hashParams = new URLSearchParams(window.location.hash.substring(1));
1679
+ const queryParams = new URLSearchParams(window.location.search);
1680
+ const accessToken = hashParams.get("access_token") || queryParams.get("access_token");
1681
+ const refreshToken = hashParams.get("refresh_token") || queryParams.get("refresh_token");
1682
+ const errorParam = hashParams.get("error") || queryParams.get("error");
1683
+ const errorDescription = hashParams.get("error_description") || queryParams.get("error_description");
1684
+ if (errorParam) {
1685
+ const msg = errorDescription || errorParam;
1686
+ error.value = msg;
1687
+ const e = new Error(msg);
1688
+ emit("error", e);
1689
+ props.onError?.(e);
1690
+ return;
1691
+ }
1692
+ if (accessToken) try {
1693
+ await client.setSession({
1694
+ access_token: accessToken,
1695
+ refresh_token: refreshToken || void 0
1696
+ });
1697
+ emit("success");
1698
+ props.onSuccess?.();
1699
+ } catch (err) {
1700
+ const message = err.message || "Failed to set session";
1701
+ error.value = message;
1702
+ const e = err instanceof Error ? err : new Error(message);
1703
+ emit("error", e);
1704
+ props.onError?.(e);
1705
+ }
1706
+ else {
1707
+ const message = "No authentication tokens found in callback URL.";
1708
+ error.value = message;
1709
+ const e = /* @__PURE__ */ new Error(message);
1710
+ emit("error", e);
1711
+ props.onError?.(e);
1712
+ }
1713
+ });
1714
+ return () => {
1715
+ const slotProps = { error: error.value };
1716
+ if (slots.default) return slots.default(slotProps);
1717
+ return (0, vue.h)("div", { "data-authos-callback": "" }, [error.value ? (0, vue.h)("div", { "data-authos-error": "" }, error.value) : (0, vue.h)("div", { "data-authos-loading": "" }, "Completing sign in...")]);
1718
+ };
1719
+ }
1665
1720
  });
1666
-
1721
+ //#endregion
1722
+ exports.AUTH_OS_INJECTION_KEY = require_useAuthOS.AUTH_OS_INJECTION_KEY;
1667
1723
  Object.defineProperty(exports, "AuthErrorCodes", {
1668
- enumerable: true,
1669
- get: function () { return ssoSdk.AuthErrorCodes; }
1724
+ enumerable: true,
1725
+ get: function() {
1726
+ return _drmhse_sso_sdk.AuthErrorCodes;
1727
+ }
1670
1728
  });
1729
+ exports.AuthOSProvider = AuthOSProvider;
1671
1730
  Object.defineProperty(exports, "BrowserStorage", {
1672
- enumerable: true,
1673
- get: function () { return ssoSdk.BrowserStorage; }
1731
+ enumerable: true,
1732
+ get: function() {
1733
+ return _drmhse_sso_sdk.BrowserStorage;
1734
+ }
1674
1735
  });
1675
- Object.defineProperty(exports, "MemoryStorage", {
1676
- enumerable: true,
1677
- get: function () { return ssoSdk.MemoryStorage; }
1678
- });
1679
- Object.defineProperty(exports, "SsoApiError", {
1680
- enumerable: true,
1681
- get: function () { return ssoSdk.SsoApiError; }
1682
- });
1683
- exports.AUTH_OS_INJECTION_KEY = AUTH_OS_INJECTION_KEY;
1684
- exports.AuthOSProvider = AuthOSProvider;
1685
1736
  exports.Callback = Callback;
1686
1737
  exports.MagicLinkSignIn = MagicLinkSignIn;
1738
+ Object.defineProperty(exports, "MemoryStorage", {
1739
+ enumerable: true,
1740
+ get: function() {
1741
+ return _drmhse_sso_sdk.MemoryStorage;
1742
+ }
1743
+ });
1687
1744
  exports.OAuthButton = OAuthButton;
1688
1745
  exports.OrganizationSwitcher = OrganizationSwitcher;
1689
1746
  exports.PasskeySignIn = PasskeySignIn;
@@ -1692,11 +1749,17 @@ exports.SignIn = SignIn;
1692
1749
  exports.SignUp = SignUp;
1693
1750
  exports.SignedIn = SignedIn;
1694
1751
  exports.SignedOut = SignedOut;
1752
+ Object.defineProperty(exports, "SsoApiError", {
1753
+ enumerable: true,
1754
+ get: function() {
1755
+ return _drmhse_sso_sdk.SsoApiError;
1756
+ }
1757
+ });
1695
1758
  exports.UserButton = UserButton;
1696
1759
  exports.createAuthOS = createAuthOS;
1697
1760
  exports.useAllPermissions = useAllPermissions;
1698
1761
  exports.useAnyPermission = useAnyPermission;
1699
- exports.useAuthOS = useAuthOS;
1762
+ exports.useAuthOS = require_useAuthOS.useAuthOS;
1700
1763
  exports.useOrganization = useOrganization;
1701
1764
  exports.usePermission = usePermission;
1702
1765
  exports.useUser = useUser;