@drmhse/authos-vue 0.2.0 → 0.2.2
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/README.md +36 -1
- package/dist/index.d.mts +39 -5
- package/dist/index.d.ts +39 -5
- package/dist/index.js +219 -129
- package/dist/index.mjs +219 -129
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -398,7 +398,40 @@ export default defineEventHandler(async (event) => {
|
|
|
398
398
|
|
|
399
399
|
## Styling
|
|
400
400
|
|
|
401
|
-
|
|
401
|
+
AuthOS components come with **polished default styling** out of the box, similar to best-in-class auth providers. The styling is fully customizable via the `appearance` option or by overriding CSS variables.
|
|
402
|
+
|
|
403
|
+
### Customization
|
|
404
|
+
|
|
405
|
+
You can customize the theme colors, fonts, and more by passing an `appearance` object to `createAuthOS`.
|
|
406
|
+
|
|
407
|
+
```ts
|
|
408
|
+
app.use(createAuthOS({
|
|
409
|
+
// ... other options
|
|
410
|
+
appearance: {
|
|
411
|
+
variables: {
|
|
412
|
+
colorPrimary: '#0066cc',
|
|
413
|
+
colorBackground: '#f5f5f5',
|
|
414
|
+
borderRadius: '0.25rem',
|
|
415
|
+
fontFamily: 'Inter, sans-serif',
|
|
416
|
+
},
|
|
417
|
+
},
|
|
418
|
+
}));
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
### CSS Variables
|
|
422
|
+
|
|
423
|
+
You can also override these CSS variables in your own stylesheet:
|
|
424
|
+
|
|
425
|
+
```css
|
|
426
|
+
:root {
|
|
427
|
+
--authos-color-primary: #0066cc;
|
|
428
|
+
--authos-border-radius: 4px;
|
|
429
|
+
}
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Headless Styling
|
|
433
|
+
|
|
434
|
+
If you prefer to completely style the components yourself, you can target the data attributes. The default styles have low specificity, so your CSS classes will easily override them.
|
|
402
435
|
|
|
403
436
|
```css
|
|
404
437
|
[data-authos-signin] { /* Container */ }
|
|
@@ -409,6 +442,8 @@ All components use data attributes for styling hooks:
|
|
|
409
442
|
[data-authos-oauth] { /* OAuth button */ }
|
|
410
443
|
[data-authos-oauth][data-provider="github"] { /* GitHub button */ }
|
|
411
444
|
[data-authos-divider] { /* "or" divider */ }
|
|
445
|
+
[data-authos-magic-link] { /* Magic Link container */ }
|
|
446
|
+
[data-authos-passkey] { /* Passkey container */ }
|
|
412
447
|
```
|
|
413
448
|
|
|
414
449
|
## Migration from v1
|
package/dist/index.d.mts
CHANGED
|
@@ -158,7 +158,7 @@ declare const AUTH_OS_INJECTION_KEY: unique symbol;
|
|
|
158
158
|
/**
|
|
159
159
|
* Supported OAuth providers
|
|
160
160
|
*/
|
|
161
|
-
type SupportedOAuthProvider = 'github' | 'google' | 'microsoft';
|
|
161
|
+
type SupportedOAuthProvider$1 = 'github' | 'google' | 'microsoft';
|
|
162
162
|
|
|
163
163
|
declare function createAuthOS(options: AuthOSPluginOptions): {
|
|
164
164
|
install(app: App): void;
|
|
@@ -383,6 +383,7 @@ declare const SignIn: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
383
383
|
onError: (error: Error) => void;
|
|
384
384
|
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
|
385
385
|
|
|
386
|
+
type SupportedOAuthProvider = 'github' | 'google' | 'microsoft';
|
|
386
387
|
interface SignUpSlotProps {
|
|
387
388
|
email: string;
|
|
388
389
|
password: string;
|
|
@@ -411,6 +412,21 @@ declare const SignUp: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
411
412
|
type: StringConstructor;
|
|
412
413
|
default: undefined;
|
|
413
414
|
};
|
|
415
|
+
/** List of OAuth providers to display buttons for */
|
|
416
|
+
providers: {
|
|
417
|
+
type: PropType<SupportedOAuthProvider[] | false>;
|
|
418
|
+
default: boolean;
|
|
419
|
+
};
|
|
420
|
+
/** Show divider between OAuth and email form */
|
|
421
|
+
showDivider: {
|
|
422
|
+
type: BooleanConstructor;
|
|
423
|
+
default: boolean;
|
|
424
|
+
};
|
|
425
|
+
/** Show sign in link */
|
|
426
|
+
showSignIn: {
|
|
427
|
+
type: BooleanConstructor;
|
|
428
|
+
default: boolean;
|
|
429
|
+
};
|
|
414
430
|
}>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
|
|
415
431
|
[key: string]: any;
|
|
416
432
|
}> | vue.VNode<vue.RendererNode, vue.RendererElement, {
|
|
@@ -434,6 +450,21 @@ declare const SignUp: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
434
450
|
type: StringConstructor;
|
|
435
451
|
default: undefined;
|
|
436
452
|
};
|
|
453
|
+
/** List of OAuth providers to display buttons for */
|
|
454
|
+
providers: {
|
|
455
|
+
type: PropType<SupportedOAuthProvider[] | false>;
|
|
456
|
+
default: boolean;
|
|
457
|
+
};
|
|
458
|
+
/** Show divider between OAuth and email form */
|
|
459
|
+
showDivider: {
|
|
460
|
+
type: BooleanConstructor;
|
|
461
|
+
default: boolean;
|
|
462
|
+
};
|
|
463
|
+
/** Show sign in link */
|
|
464
|
+
showSignIn: {
|
|
465
|
+
type: BooleanConstructor;
|
|
466
|
+
default: boolean;
|
|
467
|
+
};
|
|
437
468
|
}>> & Readonly<{
|
|
438
469
|
onSuccess?: ((...args: any[]) => any) | undefined;
|
|
439
470
|
onError?: ((...args: any[]) => any) | undefined;
|
|
@@ -442,6 +473,9 @@ declare const SignUp: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
442
473
|
onError: (error: Error) => void;
|
|
443
474
|
orgSlug: string;
|
|
444
475
|
serviceSlug: string;
|
|
476
|
+
providers: false | SupportedOAuthProvider[];
|
|
477
|
+
showDivider: boolean;
|
|
478
|
+
showSignIn: boolean;
|
|
445
479
|
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
|
446
480
|
|
|
447
481
|
interface OrganizationSwitcherSlotProps {
|
|
@@ -542,7 +576,7 @@ declare const Protect: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
542
576
|
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
|
543
577
|
|
|
544
578
|
interface OAuthButtonSlotProps {
|
|
545
|
-
provider: SupportedOAuthProvider;
|
|
579
|
+
provider: SupportedOAuthProvider$1;
|
|
546
580
|
providerName: string;
|
|
547
581
|
isConfigured: boolean;
|
|
548
582
|
disabled: boolean;
|
|
@@ -568,7 +602,7 @@ interface OAuthButtonSlotProps {
|
|
|
568
602
|
*/
|
|
569
603
|
declare const OAuthButton: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
570
604
|
provider: {
|
|
571
|
-
type: PropType<SupportedOAuthProvider>;
|
|
605
|
+
type: PropType<SupportedOAuthProvider$1>;
|
|
572
606
|
required: true;
|
|
573
607
|
};
|
|
574
608
|
disabled: {
|
|
@@ -581,7 +615,7 @@ declare const OAuthButton: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
581
615
|
[key: string]: any;
|
|
582
616
|
}>[], {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, "redirect"[], "redirect", vue.PublicProps, Readonly<vue.ExtractPropTypes<{
|
|
583
617
|
provider: {
|
|
584
|
-
type: PropType<SupportedOAuthProvider>;
|
|
618
|
+
type: PropType<SupportedOAuthProvider$1>;
|
|
585
619
|
required: true;
|
|
586
620
|
};
|
|
587
621
|
disabled: {
|
|
@@ -721,4 +755,4 @@ declare const PasskeySignIn: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
721
755
|
showPasswordSignIn: boolean;
|
|
722
756
|
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
|
723
757
|
|
|
724
|
-
export { AUTH_OS_INJECTION_KEY, type AppearanceOptions, type AppearanceVariables, type AuthOSContext, type AuthOSPluginOptions, AuthOSProvider, type AuthOSState, MagicLinkSignIn, OAuthButton, type OAuthButtonSlotProps, OrganizationSwitcher, type OrganizationSwitcherSlotProps, PasskeySignIn, Protect, SignIn, type SignInSlotProps, SignUp, type SignUpSlotProps, SignedIn, SignedOut, type SupportedOAuthProvider, UserButton, type UserButtonSlotProps, createAuthOS, useAllPermissions, useAnyPermission, useAuthOS, useOrganization, usePermission, useUser };
|
|
758
|
+
export { AUTH_OS_INJECTION_KEY, type AppearanceOptions, type AppearanceVariables, type AuthOSContext, type AuthOSPluginOptions, AuthOSProvider, type AuthOSState, MagicLinkSignIn, OAuthButton, type OAuthButtonSlotProps, OrganizationSwitcher, type OrganizationSwitcherSlotProps, PasskeySignIn, Protect, SignIn, type SignInSlotProps, SignUp, type SignUpSlotProps, SignedIn, SignedOut, type SupportedOAuthProvider$1 as SupportedOAuthProvider, UserButton, type UserButtonSlotProps, createAuthOS, useAllPermissions, useAnyPermission, useAuthOS, useOrganization, usePermission, useUser };
|
package/dist/index.d.ts
CHANGED
|
@@ -158,7 +158,7 @@ declare const AUTH_OS_INJECTION_KEY: unique symbol;
|
|
|
158
158
|
/**
|
|
159
159
|
* Supported OAuth providers
|
|
160
160
|
*/
|
|
161
|
-
type SupportedOAuthProvider = 'github' | 'google' | 'microsoft';
|
|
161
|
+
type SupportedOAuthProvider$1 = 'github' | 'google' | 'microsoft';
|
|
162
162
|
|
|
163
163
|
declare function createAuthOS(options: AuthOSPluginOptions): {
|
|
164
164
|
install(app: App): void;
|
|
@@ -383,6 +383,7 @@ declare const SignIn: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
383
383
|
onError: (error: Error) => void;
|
|
384
384
|
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
|
385
385
|
|
|
386
|
+
type SupportedOAuthProvider = 'github' | 'google' | 'microsoft';
|
|
386
387
|
interface SignUpSlotProps {
|
|
387
388
|
email: string;
|
|
388
389
|
password: string;
|
|
@@ -411,6 +412,21 @@ declare const SignUp: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
411
412
|
type: StringConstructor;
|
|
412
413
|
default: undefined;
|
|
413
414
|
};
|
|
415
|
+
/** List of OAuth providers to display buttons for */
|
|
416
|
+
providers: {
|
|
417
|
+
type: PropType<SupportedOAuthProvider[] | false>;
|
|
418
|
+
default: boolean;
|
|
419
|
+
};
|
|
420
|
+
/** Show divider between OAuth and email form */
|
|
421
|
+
showDivider: {
|
|
422
|
+
type: BooleanConstructor;
|
|
423
|
+
default: boolean;
|
|
424
|
+
};
|
|
425
|
+
/** Show sign in link */
|
|
426
|
+
showSignIn: {
|
|
427
|
+
type: BooleanConstructor;
|
|
428
|
+
default: boolean;
|
|
429
|
+
};
|
|
414
430
|
}>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
|
|
415
431
|
[key: string]: any;
|
|
416
432
|
}> | vue.VNode<vue.RendererNode, vue.RendererElement, {
|
|
@@ -434,6 +450,21 @@ declare const SignUp: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
434
450
|
type: StringConstructor;
|
|
435
451
|
default: undefined;
|
|
436
452
|
};
|
|
453
|
+
/** List of OAuth providers to display buttons for */
|
|
454
|
+
providers: {
|
|
455
|
+
type: PropType<SupportedOAuthProvider[] | false>;
|
|
456
|
+
default: boolean;
|
|
457
|
+
};
|
|
458
|
+
/** Show divider between OAuth and email form */
|
|
459
|
+
showDivider: {
|
|
460
|
+
type: BooleanConstructor;
|
|
461
|
+
default: boolean;
|
|
462
|
+
};
|
|
463
|
+
/** Show sign in link */
|
|
464
|
+
showSignIn: {
|
|
465
|
+
type: BooleanConstructor;
|
|
466
|
+
default: boolean;
|
|
467
|
+
};
|
|
437
468
|
}>> & Readonly<{
|
|
438
469
|
onSuccess?: ((...args: any[]) => any) | undefined;
|
|
439
470
|
onError?: ((...args: any[]) => any) | undefined;
|
|
@@ -442,6 +473,9 @@ declare const SignUp: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
442
473
|
onError: (error: Error) => void;
|
|
443
474
|
orgSlug: string;
|
|
444
475
|
serviceSlug: string;
|
|
476
|
+
providers: false | SupportedOAuthProvider[];
|
|
477
|
+
showDivider: boolean;
|
|
478
|
+
showSignIn: boolean;
|
|
445
479
|
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
|
446
480
|
|
|
447
481
|
interface OrganizationSwitcherSlotProps {
|
|
@@ -542,7 +576,7 @@ declare const Protect: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
542
576
|
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
|
543
577
|
|
|
544
578
|
interface OAuthButtonSlotProps {
|
|
545
|
-
provider: SupportedOAuthProvider;
|
|
579
|
+
provider: SupportedOAuthProvider$1;
|
|
546
580
|
providerName: string;
|
|
547
581
|
isConfigured: boolean;
|
|
548
582
|
disabled: boolean;
|
|
@@ -568,7 +602,7 @@ interface OAuthButtonSlotProps {
|
|
|
568
602
|
*/
|
|
569
603
|
declare const OAuthButton: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
570
604
|
provider: {
|
|
571
|
-
type: PropType<SupportedOAuthProvider>;
|
|
605
|
+
type: PropType<SupportedOAuthProvider$1>;
|
|
572
606
|
required: true;
|
|
573
607
|
};
|
|
574
608
|
disabled: {
|
|
@@ -581,7 +615,7 @@ declare const OAuthButton: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
581
615
|
[key: string]: any;
|
|
582
616
|
}>[], {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, "redirect"[], "redirect", vue.PublicProps, Readonly<vue.ExtractPropTypes<{
|
|
583
617
|
provider: {
|
|
584
|
-
type: PropType<SupportedOAuthProvider>;
|
|
618
|
+
type: PropType<SupportedOAuthProvider$1>;
|
|
585
619
|
required: true;
|
|
586
620
|
};
|
|
587
621
|
disabled: {
|
|
@@ -721,4 +755,4 @@ declare const PasskeySignIn: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
721
755
|
showPasswordSignIn: boolean;
|
|
722
756
|
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
|
723
757
|
|
|
724
|
-
export { AUTH_OS_INJECTION_KEY, type AppearanceOptions, type AppearanceVariables, type AuthOSContext, type AuthOSPluginOptions, AuthOSProvider, type AuthOSState, MagicLinkSignIn, OAuthButton, type OAuthButtonSlotProps, OrganizationSwitcher, type OrganizationSwitcherSlotProps, PasskeySignIn, Protect, SignIn, type SignInSlotProps, SignUp, type SignUpSlotProps, SignedIn, SignedOut, type SupportedOAuthProvider, UserButton, type UserButtonSlotProps, createAuthOS, useAllPermissions, useAnyPermission, useAuthOS, useOrganization, usePermission, useUser };
|
|
758
|
+
export { AUTH_OS_INJECTION_KEY, type AppearanceOptions, type AppearanceVariables, type AuthOSContext, type AuthOSPluginOptions, AuthOSProvider, type AuthOSState, MagicLinkSignIn, OAuthButton, type OAuthButtonSlotProps, OrganizationSwitcher, type OrganizationSwitcherSlotProps, PasskeySignIn, Protect, SignIn, type SignInSlotProps, SignUp, type SignUpSlotProps, SignedIn, SignedOut, type SupportedOAuthProvider$1 as SupportedOAuthProvider, UserButton, type UserButtonSlotProps, createAuthOS, useAllPermissions, useAnyPermission, useAuthOS, useOrganization, usePermission, useUser };
|
package/dist/index.js
CHANGED
|
@@ -92,23 +92,38 @@ var AUTHOS_STYLES = `
|
|
|
92
92
|
Base Form Styles
|
|
93
93
|
========================================================================== */
|
|
94
94
|
|
|
95
|
+
/* ==========================================================================
|
|
96
|
+
Base Form Styles (Card Layout)
|
|
97
|
+
========================================================================== */
|
|
98
|
+
|
|
95
99
|
[data-authos-signin],
|
|
96
100
|
[data-authos-signup],
|
|
97
|
-
[data-authos-
|
|
101
|
+
[data-authos-magic-link],
|
|
98
102
|
[data-authos-passkey] {
|
|
99
103
|
font-family: var(--authos-font-family);
|
|
100
104
|
font-size: var(--authos-font-size-sm);
|
|
101
105
|
color: var(--authos-color-foreground);
|
|
106
|
+
|
|
107
|
+
/* Card Styling */
|
|
108
|
+
background-color: var(--authos-color-surface);
|
|
109
|
+
border: 1px solid var(--authos-color-border);
|
|
110
|
+
border-radius: var(--authos-border-radius-lg);
|
|
111
|
+
box-shadow: var(--authos-shadow);
|
|
112
|
+
padding: 2rem;
|
|
102
113
|
width: 100%;
|
|
114
|
+
max-width: 25rem; /* 400px */
|
|
115
|
+
margin: 0 auto; /* Center horizontally */
|
|
103
116
|
}
|
|
104
117
|
|
|
118
|
+
/* Ensure forms inside take full width */
|
|
105
119
|
[data-authos-signin] form,
|
|
106
120
|
[data-authos-signup] form,
|
|
107
|
-
[data-authos-
|
|
121
|
+
[data-authos-magic-link] form,
|
|
108
122
|
[data-authos-passkey] form {
|
|
109
123
|
display: flex;
|
|
110
124
|
flex-direction: column;
|
|
111
125
|
gap: var(--authos-spacing-md);
|
|
126
|
+
width: 100%;
|
|
112
127
|
}
|
|
113
128
|
|
|
114
129
|
/* ==========================================================================
|
|
@@ -857,6 +872,133 @@ var SignIn = vue.defineComponent({
|
|
|
857
872
|
};
|
|
858
873
|
}
|
|
859
874
|
});
|
|
875
|
+
var PROVIDER_NAMES = {
|
|
876
|
+
github: "GitHub",
|
|
877
|
+
google: "Google",
|
|
878
|
+
microsoft: "Microsoft"
|
|
879
|
+
};
|
|
880
|
+
function getProviderIcon(provider) {
|
|
881
|
+
switch (provider) {
|
|
882
|
+
case "github":
|
|
883
|
+
return vue.h("svg", {
|
|
884
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
885
|
+
viewBox: "0 0 24 24",
|
|
886
|
+
fill: "currentColor",
|
|
887
|
+
"aria-hidden": "true"
|
|
888
|
+
}, [
|
|
889
|
+
vue.h("path", {
|
|
890
|
+
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"
|
|
891
|
+
})
|
|
892
|
+
]);
|
|
893
|
+
case "google":
|
|
894
|
+
return vue.h("svg", {
|
|
895
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
896
|
+
viewBox: "0 0 24 24",
|
|
897
|
+
"aria-hidden": "true"
|
|
898
|
+
}, [
|
|
899
|
+
vue.h("path", {
|
|
900
|
+
fill: "#4285F4",
|
|
901
|
+
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"
|
|
902
|
+
}),
|
|
903
|
+
vue.h("path", {
|
|
904
|
+
fill: "#34A853",
|
|
905
|
+
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"
|
|
906
|
+
}),
|
|
907
|
+
vue.h("path", {
|
|
908
|
+
fill: "#FBBC05",
|
|
909
|
+
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"
|
|
910
|
+
}),
|
|
911
|
+
vue.h("path", {
|
|
912
|
+
fill: "#EA4335",
|
|
913
|
+
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"
|
|
914
|
+
})
|
|
915
|
+
]);
|
|
916
|
+
case "microsoft":
|
|
917
|
+
return vue.h("svg", {
|
|
918
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
919
|
+
viewBox: "0 0 23 23",
|
|
920
|
+
"aria-hidden": "true"
|
|
921
|
+
}, [
|
|
922
|
+
vue.h("path", { fill: "#f35325", d: "M1 1h10v10H1z" }),
|
|
923
|
+
vue.h("path", { fill: "#81bc06", d: "M12 1h10v10H12z" }),
|
|
924
|
+
vue.h("path", { fill: "#05a6f0", d: "M1 12h10v10H1z" }),
|
|
925
|
+
vue.h("path", { fill: "#ffba08", d: "M12 12h10v10H12z" })
|
|
926
|
+
]);
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
var OAuthButton = vue.defineComponent({
|
|
930
|
+
name: "OAuthButton",
|
|
931
|
+
props: {
|
|
932
|
+
provider: {
|
|
933
|
+
type: String,
|
|
934
|
+
required: true
|
|
935
|
+
},
|
|
936
|
+
disabled: {
|
|
937
|
+
type: Boolean,
|
|
938
|
+
default: false
|
|
939
|
+
}
|
|
940
|
+
},
|
|
941
|
+
emits: ["redirect"],
|
|
942
|
+
setup(props, { slots, emit }) {
|
|
943
|
+
const { client, options } = useAuthOS();
|
|
944
|
+
const isConfigured = vue.computed(() => !!(options.org && options.service));
|
|
945
|
+
const providerName = vue.computed(() => PROVIDER_NAMES[props.provider]);
|
|
946
|
+
function handleClick() {
|
|
947
|
+
if (!options.org || !options.service) {
|
|
948
|
+
console.error(
|
|
949
|
+
`[AuthOS] OAuth login requires "org" and "service" in createAuthOS options.
|
|
950
|
+
Current options: { org: ${options.org ? `"${options.org}"` : "undefined"}, service: ${options.service ? `"${options.service}"` : "undefined"} }
|
|
951
|
+
|
|
952
|
+
Example:
|
|
953
|
+
app.use(createAuthOS({
|
|
954
|
+
baseURL: "${options.baseURL}",
|
|
955
|
+
org: "your-org-slug",
|
|
956
|
+
service: "your-service-slug",
|
|
957
|
+
}));
|
|
958
|
+
|
|
959
|
+
See: https://docs.authos.dev/vue/oauth-setup`
|
|
960
|
+
);
|
|
961
|
+
return;
|
|
962
|
+
}
|
|
963
|
+
const redirectUri = options.redirectUri ?? (typeof window !== "undefined" ? window.location.origin + "/callback" : void 0);
|
|
964
|
+
const url = client.auth.getLoginUrl(props.provider, {
|
|
965
|
+
org: options.org,
|
|
966
|
+
service: options.service,
|
|
967
|
+
redirect_uri: redirectUri
|
|
968
|
+
});
|
|
969
|
+
emit("redirect");
|
|
970
|
+
window.location.href = url;
|
|
971
|
+
}
|
|
972
|
+
return () => {
|
|
973
|
+
const slotProps = {
|
|
974
|
+
provider: props.provider,
|
|
975
|
+
providerName: providerName.value,
|
|
976
|
+
isConfigured: isConfigured.value,
|
|
977
|
+
disabled: props.disabled,
|
|
978
|
+
handleClick
|
|
979
|
+
};
|
|
980
|
+
if (slots.default) {
|
|
981
|
+
return slots.default(slotProps);
|
|
982
|
+
}
|
|
983
|
+
return vue.h(
|
|
984
|
+
"button",
|
|
985
|
+
{
|
|
986
|
+
type: "button",
|
|
987
|
+
onClick: handleClick,
|
|
988
|
+
disabled: props.disabled || !isConfigured.value,
|
|
989
|
+
"data-authos-oauth": "",
|
|
990
|
+
"data-provider": props.provider
|
|
991
|
+
},
|
|
992
|
+
[
|
|
993
|
+
getProviderIcon(props.provider),
|
|
994
|
+
vue.h("span", `Continue with ${providerName.value}`)
|
|
995
|
+
]
|
|
996
|
+
);
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
});
|
|
1000
|
+
|
|
1001
|
+
// src/components/SignUp.ts
|
|
860
1002
|
var SignUp = vue.defineComponent({
|
|
861
1003
|
name: "SignUp",
|
|
862
1004
|
props: {
|
|
@@ -877,17 +1019,44 @@ var SignUp = vue.defineComponent({
|
|
|
877
1019
|
serviceSlug: {
|
|
878
1020
|
type: String,
|
|
879
1021
|
default: void 0
|
|
1022
|
+
},
|
|
1023
|
+
/** List of OAuth providers to display buttons for */
|
|
1024
|
+
providers: {
|
|
1025
|
+
type: [Array, Boolean],
|
|
1026
|
+
default: false
|
|
1027
|
+
},
|
|
1028
|
+
/** Show divider between OAuth and email form */
|
|
1029
|
+
showDivider: {
|
|
1030
|
+
type: Boolean,
|
|
1031
|
+
default: true
|
|
1032
|
+
},
|
|
1033
|
+
/** Show sign in link */
|
|
1034
|
+
showSignIn: {
|
|
1035
|
+
type: Boolean,
|
|
1036
|
+
default: true
|
|
880
1037
|
}
|
|
881
1038
|
},
|
|
882
1039
|
emits: ["success", "error"],
|
|
883
1040
|
setup(props, { slots, emit }) {
|
|
884
|
-
const { client } = useAuthOS();
|
|
1041
|
+
const { client, options } = useAuthOS();
|
|
885
1042
|
const email = vue.ref("");
|
|
886
1043
|
const password = vue.ref("");
|
|
1044
|
+
const confirmPassword = vue.ref("");
|
|
887
1045
|
const error = vue.ref(null);
|
|
888
1046
|
const isSubmitting = vue.ref(false);
|
|
1047
|
+
const isSuccess = vue.ref(false);
|
|
1048
|
+
const hasOAuthConfig = !!(options.org && options.service);
|
|
1049
|
+
const oauthProviders = Array.isArray(props.providers) ? props.providers : [];
|
|
889
1050
|
async function submit() {
|
|
890
1051
|
error.value = null;
|
|
1052
|
+
if (password.value !== confirmPassword.value) {
|
|
1053
|
+
error.value = "Passwords do not match";
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1056
|
+
if (password.value.length < 8) {
|
|
1057
|
+
error.value = "Password must be at least 8 characters";
|
|
1058
|
+
return;
|
|
1059
|
+
}
|
|
891
1060
|
isSubmitting.value = true;
|
|
892
1061
|
try {
|
|
893
1062
|
await client.auth.register({
|
|
@@ -896,6 +1065,7 @@ var SignUp = vue.defineComponent({
|
|
|
896
1065
|
org_slug: props.orgSlug,
|
|
897
1066
|
service_slug: props.serviceSlug
|
|
898
1067
|
});
|
|
1068
|
+
isSuccess.value = true;
|
|
899
1069
|
emit("success");
|
|
900
1070
|
props.onSuccess?.();
|
|
901
1071
|
} catch (err) {
|
|
@@ -921,7 +1091,33 @@ var SignUp = vue.defineComponent({
|
|
|
921
1091
|
if (slots.default) {
|
|
922
1092
|
return slots.default(slotProps);
|
|
923
1093
|
}
|
|
1094
|
+
if (isSuccess.value) {
|
|
1095
|
+
return vue.h("div", { "data-authos-signup": "", "data-state": "success" }, [
|
|
1096
|
+
vue.h("div", { "data-authos-success": "" }, [
|
|
1097
|
+
vue.h("h2", "Check your email"),
|
|
1098
|
+
vue.h("p", `We've sent a verification link to ${email.value}. Please click the link to verify your account.`)
|
|
1099
|
+
])
|
|
1100
|
+
]);
|
|
1101
|
+
}
|
|
924
1102
|
return vue.h("div", { "data-authos-signup": "", "data-state": "credentials" }, [
|
|
1103
|
+
// OAuth Section
|
|
1104
|
+
oauthProviders.length > 0 && vue.h("div", { "data-authos-oauth-section": "" }, [
|
|
1105
|
+
oauthProviders.map(
|
|
1106
|
+
(provider) => vue.h(OAuthButton, {
|
|
1107
|
+
key: provider,
|
|
1108
|
+
provider,
|
|
1109
|
+
disabled: isSubmitting.value || !hasOAuthConfig
|
|
1110
|
+
})
|
|
1111
|
+
),
|
|
1112
|
+
!hasOAuthConfig && vue.h("p", {
|
|
1113
|
+
"data-authos-oauth-warning": "",
|
|
1114
|
+
style: { color: "orange", fontSize: "0.875rem" }
|
|
1115
|
+
}, "OAuth requires org and service in plugin options")
|
|
1116
|
+
]),
|
|
1117
|
+
// Divider
|
|
1118
|
+
oauthProviders.length > 0 && props.showDivider && vue.h("div", { "data-authos-divider": "" }, [
|
|
1119
|
+
vue.h("span", "or")
|
|
1120
|
+
]),
|
|
925
1121
|
vue.h("form", { onSubmit: (e) => {
|
|
926
1122
|
e.preventDefault();
|
|
927
1123
|
submit();
|
|
@@ -952,12 +1148,31 @@ var SignUp = vue.defineComponent({
|
|
|
952
1148
|
onInput: (e) => password.value = e.target.value
|
|
953
1149
|
})
|
|
954
1150
|
]),
|
|
1151
|
+
// Confirm Password
|
|
1152
|
+
vue.h("div", { "data-authos-field": "confirm-password" }, [
|
|
1153
|
+
vue.h("label", { for: "authos-signup-confirm" }, "Confirm Password"),
|
|
1154
|
+
vue.h("input", {
|
|
1155
|
+
id: "authos-signup-confirm",
|
|
1156
|
+
type: "password",
|
|
1157
|
+
autocomplete: "new-password",
|
|
1158
|
+
value: confirmPassword.value,
|
|
1159
|
+
placeholder: "Confirm your password",
|
|
1160
|
+
required: true,
|
|
1161
|
+
disabled: isSubmitting.value,
|
|
1162
|
+
onInput: (e) => confirmPassword.value = e.target.value
|
|
1163
|
+
})
|
|
1164
|
+
]),
|
|
955
1165
|
error.value && vue.h("div", { "data-authos-error": "" }, error.value),
|
|
956
1166
|
vue.h("button", {
|
|
957
1167
|
type: "submit",
|
|
958
1168
|
disabled: isSubmitting.value,
|
|
959
1169
|
"data-authos-submit": ""
|
|
960
|
-
}, isSubmitting.value ? "Creating account..." : "Sign Up")
|
|
1170
|
+
}, isSubmitting.value ? "Creating account..." : "Sign Up"),
|
|
1171
|
+
// Sign In Link
|
|
1172
|
+
props.showSignIn && vue.h("div", { "data-authos-signin-prompt": "" }, [
|
|
1173
|
+
"Already have an account? ",
|
|
1174
|
+
vue.h("a", { href: "/signin", "data-authos-link": "signin" }, "Sign in")
|
|
1175
|
+
])
|
|
961
1176
|
])
|
|
962
1177
|
]);
|
|
963
1178
|
};
|
|
@@ -1125,131 +1340,6 @@ var Protect = vue.defineComponent({
|
|
|
1125
1340
|
};
|
|
1126
1341
|
}
|
|
1127
1342
|
});
|
|
1128
|
-
var PROVIDER_NAMES = {
|
|
1129
|
-
github: "GitHub",
|
|
1130
|
-
google: "Google",
|
|
1131
|
-
microsoft: "Microsoft"
|
|
1132
|
-
};
|
|
1133
|
-
function getProviderIcon(provider) {
|
|
1134
|
-
switch (provider) {
|
|
1135
|
-
case "github":
|
|
1136
|
-
return vue.h("svg", {
|
|
1137
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1138
|
-
viewBox: "0 0 24 24",
|
|
1139
|
-
fill: "currentColor",
|
|
1140
|
-
"aria-hidden": "true"
|
|
1141
|
-
}, [
|
|
1142
|
-
vue.h("path", {
|
|
1143
|
-
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"
|
|
1144
|
-
})
|
|
1145
|
-
]);
|
|
1146
|
-
case "google":
|
|
1147
|
-
return vue.h("svg", {
|
|
1148
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1149
|
-
viewBox: "0 0 24 24",
|
|
1150
|
-
"aria-hidden": "true"
|
|
1151
|
-
}, [
|
|
1152
|
-
vue.h("path", {
|
|
1153
|
-
fill: "#4285F4",
|
|
1154
|
-
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"
|
|
1155
|
-
}),
|
|
1156
|
-
vue.h("path", {
|
|
1157
|
-
fill: "#34A853",
|
|
1158
|
-
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"
|
|
1159
|
-
}),
|
|
1160
|
-
vue.h("path", {
|
|
1161
|
-
fill: "#FBBC05",
|
|
1162
|
-
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"
|
|
1163
|
-
}),
|
|
1164
|
-
vue.h("path", {
|
|
1165
|
-
fill: "#EA4335",
|
|
1166
|
-
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"
|
|
1167
|
-
})
|
|
1168
|
-
]);
|
|
1169
|
-
case "microsoft":
|
|
1170
|
-
return vue.h("svg", {
|
|
1171
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1172
|
-
viewBox: "0 0 23 23",
|
|
1173
|
-
"aria-hidden": "true"
|
|
1174
|
-
}, [
|
|
1175
|
-
vue.h("path", { fill: "#f35325", d: "M1 1h10v10H1z" }),
|
|
1176
|
-
vue.h("path", { fill: "#81bc06", d: "M12 1h10v10H12z" }),
|
|
1177
|
-
vue.h("path", { fill: "#05a6f0", d: "M1 12h10v10H1z" }),
|
|
1178
|
-
vue.h("path", { fill: "#ffba08", d: "M12 12h10v10H12z" })
|
|
1179
|
-
]);
|
|
1180
|
-
}
|
|
1181
|
-
}
|
|
1182
|
-
var OAuthButton = vue.defineComponent({
|
|
1183
|
-
name: "OAuthButton",
|
|
1184
|
-
props: {
|
|
1185
|
-
provider: {
|
|
1186
|
-
type: String,
|
|
1187
|
-
required: true
|
|
1188
|
-
},
|
|
1189
|
-
disabled: {
|
|
1190
|
-
type: Boolean,
|
|
1191
|
-
default: false
|
|
1192
|
-
}
|
|
1193
|
-
},
|
|
1194
|
-
emits: ["redirect"],
|
|
1195
|
-
setup(props, { slots, emit }) {
|
|
1196
|
-
const { client, options } = useAuthOS();
|
|
1197
|
-
const isConfigured = vue.computed(() => !!(options.org && options.service));
|
|
1198
|
-
const providerName = vue.computed(() => PROVIDER_NAMES[props.provider]);
|
|
1199
|
-
function handleClick() {
|
|
1200
|
-
if (!options.org || !options.service) {
|
|
1201
|
-
console.error(
|
|
1202
|
-
`[AuthOS] OAuth login requires "org" and "service" in createAuthOS options.
|
|
1203
|
-
Current options: { org: ${options.org ? `"${options.org}"` : "undefined"}, service: ${options.service ? `"${options.service}"` : "undefined"} }
|
|
1204
|
-
|
|
1205
|
-
Example:
|
|
1206
|
-
app.use(createAuthOS({
|
|
1207
|
-
baseURL: "${options.baseURL}",
|
|
1208
|
-
org: "your-org-slug",
|
|
1209
|
-
service: "your-service-slug",
|
|
1210
|
-
}));
|
|
1211
|
-
|
|
1212
|
-
See: https://docs.authos.dev/vue/oauth-setup`
|
|
1213
|
-
);
|
|
1214
|
-
return;
|
|
1215
|
-
}
|
|
1216
|
-
const redirectUri = options.redirectUri ?? (typeof window !== "undefined" ? window.location.origin + "/callback" : void 0);
|
|
1217
|
-
const url = client.auth.getLoginUrl(props.provider, {
|
|
1218
|
-
org: options.org,
|
|
1219
|
-
service: options.service,
|
|
1220
|
-
redirect_uri: redirectUri
|
|
1221
|
-
});
|
|
1222
|
-
emit("redirect");
|
|
1223
|
-
window.location.href = url;
|
|
1224
|
-
}
|
|
1225
|
-
return () => {
|
|
1226
|
-
const slotProps = {
|
|
1227
|
-
provider: props.provider,
|
|
1228
|
-
providerName: providerName.value,
|
|
1229
|
-
isConfigured: isConfigured.value,
|
|
1230
|
-
disabled: props.disabled,
|
|
1231
|
-
handleClick
|
|
1232
|
-
};
|
|
1233
|
-
if (slots.default) {
|
|
1234
|
-
return slots.default(slotProps);
|
|
1235
|
-
}
|
|
1236
|
-
return vue.h(
|
|
1237
|
-
"button",
|
|
1238
|
-
{
|
|
1239
|
-
type: "button",
|
|
1240
|
-
onClick: handleClick,
|
|
1241
|
-
disabled: props.disabled || !isConfigured.value,
|
|
1242
|
-
"data-authos-oauth": "",
|
|
1243
|
-
"data-provider": props.provider
|
|
1244
|
-
},
|
|
1245
|
-
[
|
|
1246
|
-
getProviderIcon(props.provider),
|
|
1247
|
-
vue.h("span", `Continue with ${providerName.value}`)
|
|
1248
|
-
]
|
|
1249
|
-
);
|
|
1250
|
-
};
|
|
1251
|
-
}
|
|
1252
|
-
});
|
|
1253
1343
|
var SignedIn = vue.defineComponent({
|
|
1254
1344
|
name: "SignedIn",
|
|
1255
1345
|
setup(_, { slots }) {
|
package/dist/index.mjs
CHANGED
|
@@ -89,23 +89,38 @@ var AUTHOS_STYLES = `
|
|
|
89
89
|
Base Form Styles
|
|
90
90
|
========================================================================== */
|
|
91
91
|
|
|
92
|
+
/* ==========================================================================
|
|
93
|
+
Base Form Styles (Card Layout)
|
|
94
|
+
========================================================================== */
|
|
95
|
+
|
|
92
96
|
[data-authos-signin],
|
|
93
97
|
[data-authos-signup],
|
|
94
|
-
[data-authos-
|
|
98
|
+
[data-authos-magic-link],
|
|
95
99
|
[data-authos-passkey] {
|
|
96
100
|
font-family: var(--authos-font-family);
|
|
97
101
|
font-size: var(--authos-font-size-sm);
|
|
98
102
|
color: var(--authos-color-foreground);
|
|
103
|
+
|
|
104
|
+
/* Card Styling */
|
|
105
|
+
background-color: var(--authos-color-surface);
|
|
106
|
+
border: 1px solid var(--authos-color-border);
|
|
107
|
+
border-radius: var(--authos-border-radius-lg);
|
|
108
|
+
box-shadow: var(--authos-shadow);
|
|
109
|
+
padding: 2rem;
|
|
99
110
|
width: 100%;
|
|
111
|
+
max-width: 25rem; /* 400px */
|
|
112
|
+
margin: 0 auto; /* Center horizontally */
|
|
100
113
|
}
|
|
101
114
|
|
|
115
|
+
/* Ensure forms inside take full width */
|
|
102
116
|
[data-authos-signin] form,
|
|
103
117
|
[data-authos-signup] form,
|
|
104
|
-
[data-authos-
|
|
118
|
+
[data-authos-magic-link] form,
|
|
105
119
|
[data-authos-passkey] form {
|
|
106
120
|
display: flex;
|
|
107
121
|
flex-direction: column;
|
|
108
122
|
gap: var(--authos-spacing-md);
|
|
123
|
+
width: 100%;
|
|
109
124
|
}
|
|
110
125
|
|
|
111
126
|
/* ==========================================================================
|
|
@@ -828,6 +843,133 @@ var SignIn = defineComponent({
|
|
|
828
843
|
};
|
|
829
844
|
}
|
|
830
845
|
});
|
|
846
|
+
var PROVIDER_NAMES = {
|
|
847
|
+
github: "GitHub",
|
|
848
|
+
google: "Google",
|
|
849
|
+
microsoft: "Microsoft"
|
|
850
|
+
};
|
|
851
|
+
function getProviderIcon(provider) {
|
|
852
|
+
switch (provider) {
|
|
853
|
+
case "github":
|
|
854
|
+
return h("svg", {
|
|
855
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
856
|
+
viewBox: "0 0 24 24",
|
|
857
|
+
fill: "currentColor",
|
|
858
|
+
"aria-hidden": "true"
|
|
859
|
+
}, [
|
|
860
|
+
h("path", {
|
|
861
|
+
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"
|
|
862
|
+
})
|
|
863
|
+
]);
|
|
864
|
+
case "google":
|
|
865
|
+
return h("svg", {
|
|
866
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
867
|
+
viewBox: "0 0 24 24",
|
|
868
|
+
"aria-hidden": "true"
|
|
869
|
+
}, [
|
|
870
|
+
h("path", {
|
|
871
|
+
fill: "#4285F4",
|
|
872
|
+
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"
|
|
873
|
+
}),
|
|
874
|
+
h("path", {
|
|
875
|
+
fill: "#34A853",
|
|
876
|
+
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"
|
|
877
|
+
}),
|
|
878
|
+
h("path", {
|
|
879
|
+
fill: "#FBBC05",
|
|
880
|
+
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"
|
|
881
|
+
}),
|
|
882
|
+
h("path", {
|
|
883
|
+
fill: "#EA4335",
|
|
884
|
+
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"
|
|
885
|
+
})
|
|
886
|
+
]);
|
|
887
|
+
case "microsoft":
|
|
888
|
+
return h("svg", {
|
|
889
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
890
|
+
viewBox: "0 0 23 23",
|
|
891
|
+
"aria-hidden": "true"
|
|
892
|
+
}, [
|
|
893
|
+
h("path", { fill: "#f35325", d: "M1 1h10v10H1z" }),
|
|
894
|
+
h("path", { fill: "#81bc06", d: "M12 1h10v10H12z" }),
|
|
895
|
+
h("path", { fill: "#05a6f0", d: "M1 12h10v10H1z" }),
|
|
896
|
+
h("path", { fill: "#ffba08", d: "M12 12h10v10H12z" })
|
|
897
|
+
]);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
var OAuthButton = defineComponent({
|
|
901
|
+
name: "OAuthButton",
|
|
902
|
+
props: {
|
|
903
|
+
provider: {
|
|
904
|
+
type: String,
|
|
905
|
+
required: true
|
|
906
|
+
},
|
|
907
|
+
disabled: {
|
|
908
|
+
type: Boolean,
|
|
909
|
+
default: false
|
|
910
|
+
}
|
|
911
|
+
},
|
|
912
|
+
emits: ["redirect"],
|
|
913
|
+
setup(props, { slots, emit }) {
|
|
914
|
+
const { client, options } = useAuthOS();
|
|
915
|
+
const isConfigured = computed(() => !!(options.org && options.service));
|
|
916
|
+
const providerName = computed(() => PROVIDER_NAMES[props.provider]);
|
|
917
|
+
function handleClick() {
|
|
918
|
+
if (!options.org || !options.service) {
|
|
919
|
+
console.error(
|
|
920
|
+
`[AuthOS] OAuth login requires "org" and "service" in createAuthOS options.
|
|
921
|
+
Current options: { org: ${options.org ? `"${options.org}"` : "undefined"}, service: ${options.service ? `"${options.service}"` : "undefined"} }
|
|
922
|
+
|
|
923
|
+
Example:
|
|
924
|
+
app.use(createAuthOS({
|
|
925
|
+
baseURL: "${options.baseURL}",
|
|
926
|
+
org: "your-org-slug",
|
|
927
|
+
service: "your-service-slug",
|
|
928
|
+
}));
|
|
929
|
+
|
|
930
|
+
See: https://docs.authos.dev/vue/oauth-setup`
|
|
931
|
+
);
|
|
932
|
+
return;
|
|
933
|
+
}
|
|
934
|
+
const redirectUri = options.redirectUri ?? (typeof window !== "undefined" ? window.location.origin + "/callback" : void 0);
|
|
935
|
+
const url = client.auth.getLoginUrl(props.provider, {
|
|
936
|
+
org: options.org,
|
|
937
|
+
service: options.service,
|
|
938
|
+
redirect_uri: redirectUri
|
|
939
|
+
});
|
|
940
|
+
emit("redirect");
|
|
941
|
+
window.location.href = url;
|
|
942
|
+
}
|
|
943
|
+
return () => {
|
|
944
|
+
const slotProps = {
|
|
945
|
+
provider: props.provider,
|
|
946
|
+
providerName: providerName.value,
|
|
947
|
+
isConfigured: isConfigured.value,
|
|
948
|
+
disabled: props.disabled,
|
|
949
|
+
handleClick
|
|
950
|
+
};
|
|
951
|
+
if (slots.default) {
|
|
952
|
+
return slots.default(slotProps);
|
|
953
|
+
}
|
|
954
|
+
return h(
|
|
955
|
+
"button",
|
|
956
|
+
{
|
|
957
|
+
type: "button",
|
|
958
|
+
onClick: handleClick,
|
|
959
|
+
disabled: props.disabled || !isConfigured.value,
|
|
960
|
+
"data-authos-oauth": "",
|
|
961
|
+
"data-provider": props.provider
|
|
962
|
+
},
|
|
963
|
+
[
|
|
964
|
+
getProviderIcon(props.provider),
|
|
965
|
+
h("span", `Continue with ${providerName.value}`)
|
|
966
|
+
]
|
|
967
|
+
);
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
});
|
|
971
|
+
|
|
972
|
+
// src/components/SignUp.ts
|
|
831
973
|
var SignUp = defineComponent({
|
|
832
974
|
name: "SignUp",
|
|
833
975
|
props: {
|
|
@@ -848,17 +990,44 @@ var SignUp = defineComponent({
|
|
|
848
990
|
serviceSlug: {
|
|
849
991
|
type: String,
|
|
850
992
|
default: void 0
|
|
993
|
+
},
|
|
994
|
+
/** List of OAuth providers to display buttons for */
|
|
995
|
+
providers: {
|
|
996
|
+
type: [Array, Boolean],
|
|
997
|
+
default: false
|
|
998
|
+
},
|
|
999
|
+
/** Show divider between OAuth and email form */
|
|
1000
|
+
showDivider: {
|
|
1001
|
+
type: Boolean,
|
|
1002
|
+
default: true
|
|
1003
|
+
},
|
|
1004
|
+
/** Show sign in link */
|
|
1005
|
+
showSignIn: {
|
|
1006
|
+
type: Boolean,
|
|
1007
|
+
default: true
|
|
851
1008
|
}
|
|
852
1009
|
},
|
|
853
1010
|
emits: ["success", "error"],
|
|
854
1011
|
setup(props, { slots, emit }) {
|
|
855
|
-
const { client } = useAuthOS();
|
|
1012
|
+
const { client, options } = useAuthOS();
|
|
856
1013
|
const email = ref("");
|
|
857
1014
|
const password = ref("");
|
|
1015
|
+
const confirmPassword = ref("");
|
|
858
1016
|
const error = ref(null);
|
|
859
1017
|
const isSubmitting = ref(false);
|
|
1018
|
+
const isSuccess = ref(false);
|
|
1019
|
+
const hasOAuthConfig = !!(options.org && options.service);
|
|
1020
|
+
const oauthProviders = Array.isArray(props.providers) ? props.providers : [];
|
|
860
1021
|
async function submit() {
|
|
861
1022
|
error.value = null;
|
|
1023
|
+
if (password.value !== confirmPassword.value) {
|
|
1024
|
+
error.value = "Passwords do not match";
|
|
1025
|
+
return;
|
|
1026
|
+
}
|
|
1027
|
+
if (password.value.length < 8) {
|
|
1028
|
+
error.value = "Password must be at least 8 characters";
|
|
1029
|
+
return;
|
|
1030
|
+
}
|
|
862
1031
|
isSubmitting.value = true;
|
|
863
1032
|
try {
|
|
864
1033
|
await client.auth.register({
|
|
@@ -867,6 +1036,7 @@ var SignUp = defineComponent({
|
|
|
867
1036
|
org_slug: props.orgSlug,
|
|
868
1037
|
service_slug: props.serviceSlug
|
|
869
1038
|
});
|
|
1039
|
+
isSuccess.value = true;
|
|
870
1040
|
emit("success");
|
|
871
1041
|
props.onSuccess?.();
|
|
872
1042
|
} catch (err) {
|
|
@@ -892,7 +1062,33 @@ var SignUp = defineComponent({
|
|
|
892
1062
|
if (slots.default) {
|
|
893
1063
|
return slots.default(slotProps);
|
|
894
1064
|
}
|
|
1065
|
+
if (isSuccess.value) {
|
|
1066
|
+
return h("div", { "data-authos-signup": "", "data-state": "success" }, [
|
|
1067
|
+
h("div", { "data-authos-success": "" }, [
|
|
1068
|
+
h("h2", "Check your email"),
|
|
1069
|
+
h("p", `We've sent a verification link to ${email.value}. Please click the link to verify your account.`)
|
|
1070
|
+
])
|
|
1071
|
+
]);
|
|
1072
|
+
}
|
|
895
1073
|
return h("div", { "data-authos-signup": "", "data-state": "credentials" }, [
|
|
1074
|
+
// OAuth Section
|
|
1075
|
+
oauthProviders.length > 0 && h("div", { "data-authos-oauth-section": "" }, [
|
|
1076
|
+
oauthProviders.map(
|
|
1077
|
+
(provider) => h(OAuthButton, {
|
|
1078
|
+
key: provider,
|
|
1079
|
+
provider,
|
|
1080
|
+
disabled: isSubmitting.value || !hasOAuthConfig
|
|
1081
|
+
})
|
|
1082
|
+
),
|
|
1083
|
+
!hasOAuthConfig && h("p", {
|
|
1084
|
+
"data-authos-oauth-warning": "",
|
|
1085
|
+
style: { color: "orange", fontSize: "0.875rem" }
|
|
1086
|
+
}, "OAuth requires org and service in plugin options")
|
|
1087
|
+
]),
|
|
1088
|
+
// Divider
|
|
1089
|
+
oauthProviders.length > 0 && props.showDivider && h("div", { "data-authos-divider": "" }, [
|
|
1090
|
+
h("span", "or")
|
|
1091
|
+
]),
|
|
896
1092
|
h("form", { onSubmit: (e) => {
|
|
897
1093
|
e.preventDefault();
|
|
898
1094
|
submit();
|
|
@@ -923,12 +1119,31 @@ var SignUp = defineComponent({
|
|
|
923
1119
|
onInput: (e) => password.value = e.target.value
|
|
924
1120
|
})
|
|
925
1121
|
]),
|
|
1122
|
+
// Confirm Password
|
|
1123
|
+
h("div", { "data-authos-field": "confirm-password" }, [
|
|
1124
|
+
h("label", { for: "authos-signup-confirm" }, "Confirm Password"),
|
|
1125
|
+
h("input", {
|
|
1126
|
+
id: "authos-signup-confirm",
|
|
1127
|
+
type: "password",
|
|
1128
|
+
autocomplete: "new-password",
|
|
1129
|
+
value: confirmPassword.value,
|
|
1130
|
+
placeholder: "Confirm your password",
|
|
1131
|
+
required: true,
|
|
1132
|
+
disabled: isSubmitting.value,
|
|
1133
|
+
onInput: (e) => confirmPassword.value = e.target.value
|
|
1134
|
+
})
|
|
1135
|
+
]),
|
|
926
1136
|
error.value && h("div", { "data-authos-error": "" }, error.value),
|
|
927
1137
|
h("button", {
|
|
928
1138
|
type: "submit",
|
|
929
1139
|
disabled: isSubmitting.value,
|
|
930
1140
|
"data-authos-submit": ""
|
|
931
|
-
}, isSubmitting.value ? "Creating account..." : "Sign Up")
|
|
1141
|
+
}, isSubmitting.value ? "Creating account..." : "Sign Up"),
|
|
1142
|
+
// Sign In Link
|
|
1143
|
+
props.showSignIn && h("div", { "data-authos-signin-prompt": "" }, [
|
|
1144
|
+
"Already have an account? ",
|
|
1145
|
+
h("a", { href: "/signin", "data-authos-link": "signin" }, "Sign in")
|
|
1146
|
+
])
|
|
932
1147
|
])
|
|
933
1148
|
]);
|
|
934
1149
|
};
|
|
@@ -1096,131 +1311,6 @@ var Protect = defineComponent({
|
|
|
1096
1311
|
};
|
|
1097
1312
|
}
|
|
1098
1313
|
});
|
|
1099
|
-
var PROVIDER_NAMES = {
|
|
1100
|
-
github: "GitHub",
|
|
1101
|
-
google: "Google",
|
|
1102
|
-
microsoft: "Microsoft"
|
|
1103
|
-
};
|
|
1104
|
-
function getProviderIcon(provider) {
|
|
1105
|
-
switch (provider) {
|
|
1106
|
-
case "github":
|
|
1107
|
-
return h("svg", {
|
|
1108
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1109
|
-
viewBox: "0 0 24 24",
|
|
1110
|
-
fill: "currentColor",
|
|
1111
|
-
"aria-hidden": "true"
|
|
1112
|
-
}, [
|
|
1113
|
-
h("path", {
|
|
1114
|
-
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"
|
|
1115
|
-
})
|
|
1116
|
-
]);
|
|
1117
|
-
case "google":
|
|
1118
|
-
return h("svg", {
|
|
1119
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1120
|
-
viewBox: "0 0 24 24",
|
|
1121
|
-
"aria-hidden": "true"
|
|
1122
|
-
}, [
|
|
1123
|
-
h("path", {
|
|
1124
|
-
fill: "#4285F4",
|
|
1125
|
-
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"
|
|
1126
|
-
}),
|
|
1127
|
-
h("path", {
|
|
1128
|
-
fill: "#34A853",
|
|
1129
|
-
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"
|
|
1130
|
-
}),
|
|
1131
|
-
h("path", {
|
|
1132
|
-
fill: "#FBBC05",
|
|
1133
|
-
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"
|
|
1134
|
-
}),
|
|
1135
|
-
h("path", {
|
|
1136
|
-
fill: "#EA4335",
|
|
1137
|
-
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"
|
|
1138
|
-
})
|
|
1139
|
-
]);
|
|
1140
|
-
case "microsoft":
|
|
1141
|
-
return h("svg", {
|
|
1142
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1143
|
-
viewBox: "0 0 23 23",
|
|
1144
|
-
"aria-hidden": "true"
|
|
1145
|
-
}, [
|
|
1146
|
-
h("path", { fill: "#f35325", d: "M1 1h10v10H1z" }),
|
|
1147
|
-
h("path", { fill: "#81bc06", d: "M12 1h10v10H12z" }),
|
|
1148
|
-
h("path", { fill: "#05a6f0", d: "M1 12h10v10H1z" }),
|
|
1149
|
-
h("path", { fill: "#ffba08", d: "M12 12h10v10H12z" })
|
|
1150
|
-
]);
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
|
-
var OAuthButton = defineComponent({
|
|
1154
|
-
name: "OAuthButton",
|
|
1155
|
-
props: {
|
|
1156
|
-
provider: {
|
|
1157
|
-
type: String,
|
|
1158
|
-
required: true
|
|
1159
|
-
},
|
|
1160
|
-
disabled: {
|
|
1161
|
-
type: Boolean,
|
|
1162
|
-
default: false
|
|
1163
|
-
}
|
|
1164
|
-
},
|
|
1165
|
-
emits: ["redirect"],
|
|
1166
|
-
setup(props, { slots, emit }) {
|
|
1167
|
-
const { client, options } = useAuthOS();
|
|
1168
|
-
const isConfigured = computed(() => !!(options.org && options.service));
|
|
1169
|
-
const providerName = computed(() => PROVIDER_NAMES[props.provider]);
|
|
1170
|
-
function handleClick() {
|
|
1171
|
-
if (!options.org || !options.service) {
|
|
1172
|
-
console.error(
|
|
1173
|
-
`[AuthOS] OAuth login requires "org" and "service" in createAuthOS options.
|
|
1174
|
-
Current options: { org: ${options.org ? `"${options.org}"` : "undefined"}, service: ${options.service ? `"${options.service}"` : "undefined"} }
|
|
1175
|
-
|
|
1176
|
-
Example:
|
|
1177
|
-
app.use(createAuthOS({
|
|
1178
|
-
baseURL: "${options.baseURL}",
|
|
1179
|
-
org: "your-org-slug",
|
|
1180
|
-
service: "your-service-slug",
|
|
1181
|
-
}));
|
|
1182
|
-
|
|
1183
|
-
See: https://docs.authos.dev/vue/oauth-setup`
|
|
1184
|
-
);
|
|
1185
|
-
return;
|
|
1186
|
-
}
|
|
1187
|
-
const redirectUri = options.redirectUri ?? (typeof window !== "undefined" ? window.location.origin + "/callback" : void 0);
|
|
1188
|
-
const url = client.auth.getLoginUrl(props.provider, {
|
|
1189
|
-
org: options.org,
|
|
1190
|
-
service: options.service,
|
|
1191
|
-
redirect_uri: redirectUri
|
|
1192
|
-
});
|
|
1193
|
-
emit("redirect");
|
|
1194
|
-
window.location.href = url;
|
|
1195
|
-
}
|
|
1196
|
-
return () => {
|
|
1197
|
-
const slotProps = {
|
|
1198
|
-
provider: props.provider,
|
|
1199
|
-
providerName: providerName.value,
|
|
1200
|
-
isConfigured: isConfigured.value,
|
|
1201
|
-
disabled: props.disabled,
|
|
1202
|
-
handleClick
|
|
1203
|
-
};
|
|
1204
|
-
if (slots.default) {
|
|
1205
|
-
return slots.default(slotProps);
|
|
1206
|
-
}
|
|
1207
|
-
return h(
|
|
1208
|
-
"button",
|
|
1209
|
-
{
|
|
1210
|
-
type: "button",
|
|
1211
|
-
onClick: handleClick,
|
|
1212
|
-
disabled: props.disabled || !isConfigured.value,
|
|
1213
|
-
"data-authos-oauth": "",
|
|
1214
|
-
"data-provider": props.provider
|
|
1215
|
-
},
|
|
1216
|
-
[
|
|
1217
|
-
getProviderIcon(props.provider),
|
|
1218
|
-
h("span", `Continue with ${providerName.value}`)
|
|
1219
|
-
]
|
|
1220
|
-
);
|
|
1221
|
-
};
|
|
1222
|
-
}
|
|
1223
|
-
});
|
|
1224
1314
|
var SignedIn = defineComponent({
|
|
1225
1315
|
name: "SignedIn",
|
|
1226
1316
|
setup(_, { slots }) {
|