@drmhse/authos-vue 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -5,6 +5,441 @@ import { defineComponent, reactive, provide, onMounted, onUnmounted, h, ref, com
5
5
  import { SsoClient, BrowserStorage, MemoryStorage, SsoApiError } from '@drmhse/sso-sdk';
6
6
  export { AuthErrorCodes, BrowserStorage, MemoryStorage, SsoApiError } from '@drmhse/sso-sdk';
7
7
 
8
+ // src/styles.ts
9
+ var AUTHOS_STYLES = `
10
+ /* ==========================================================================
11
+ AuthOS Component Styles
12
+ CSS Variables + Default Theme
13
+ ========================================================================== */
14
+
15
+ :root {
16
+ /* Primary Colors */
17
+ --authos-color-primary: #6366f1;
18
+ --authos-color-primary-hover: #4f46e5;
19
+ --authos-color-primary-foreground: #ffffff;
20
+
21
+ /* Semantic Colors */
22
+ --authos-color-danger: #ef4444;
23
+ --authos-color-danger-foreground: #ffffff;
24
+ --authos-color-success: #22c55e;
25
+ --authos-color-warning: #f59e0b;
26
+
27
+ /* Surface Colors */
28
+ --authos-color-background: #ffffff;
29
+ --authos-color-surface: #ffffff;
30
+ --authos-color-foreground: #0f172a;
31
+ --authos-color-muted: #64748b;
32
+ --authos-color-muted-foreground: #64748b;
33
+
34
+ /* Component Colors */
35
+ --authos-color-border: #e2e8f0;
36
+ --authos-color-input: #ffffff;
37
+ --authos-color-input-border: #cbd5e1;
38
+ --authos-color-input-focus: #6366f1;
39
+ --authos-color-ring: rgba(99, 102, 241, 0.25);
40
+
41
+ /* Typography */
42
+ --authos-font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
43
+ --authos-font-size-xs: 0.75rem;
44
+ --authos-font-size-sm: 0.875rem;
45
+ --authos-font-size-base: 1rem;
46
+ --authos-font-size-lg: 1.125rem;
47
+
48
+ /* Spacing & Shape */
49
+ --authos-border-radius: 0.5rem;
50
+ --authos-border-radius-sm: 0.375rem;
51
+ --authos-border-radius-lg: 0.75rem;
52
+ --authos-spacing-xs: 0.25rem;
53
+ --authos-spacing-sm: 0.5rem;
54
+ --authos-spacing-md: 1rem;
55
+ --authos-spacing-lg: 1.5rem;
56
+
57
+ /* Shadows */
58
+ --authos-shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
59
+ --authos-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1);
60
+ --authos-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
61
+
62
+ /* Transitions */
63
+ --authos-transition: 150ms cubic-bezier(0.4, 0, 0.2, 1);
64
+ }
65
+
66
+ /* Dark Mode */
67
+ @media (prefers-color-scheme: dark) {
68
+ :root {
69
+ --authos-color-primary: #818cf8;
70
+ --authos-color-primary-hover: #a5b4fc;
71
+
72
+ --authos-color-background: #0f172a;
73
+ --authos-color-surface: #1e293b;
74
+ --authos-color-foreground: #f1f5f9;
75
+ --authos-color-muted: #94a3b8;
76
+ --authos-color-muted-foreground: #94a3b8;
77
+
78
+ --authos-color-border: #334155;
79
+ --authos-color-input: #1e293b;
80
+ --authos-color-input-border: #475569;
81
+
82
+ --authos-shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
83
+ --authos-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.4), 0 1px 2px -1px rgba(0, 0, 0, 0.3);
84
+ --authos-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -4px rgba(0, 0, 0, 0.3);
85
+ }
86
+ }
87
+
88
+ /* ==========================================================================
89
+ Base Form Styles
90
+ ========================================================================== */
91
+
92
+ [data-authos-signin],
93
+ [data-authos-signup],
94
+ [data-authos-magiclink],
95
+ [data-authos-passkey] {
96
+ font-family: var(--authos-font-family);
97
+ font-size: var(--authos-font-size-sm);
98
+ color: var(--authos-color-foreground);
99
+ width: 100%;
100
+ }
101
+
102
+ [data-authos-signin] form,
103
+ [data-authos-signup] form,
104
+ [data-authos-magiclink] form,
105
+ [data-authos-passkey] form {
106
+ display: flex;
107
+ flex-direction: column;
108
+ gap: var(--authos-spacing-md);
109
+ }
110
+
111
+ /* ==========================================================================
112
+ Field Styles
113
+ ========================================================================== */
114
+
115
+ [data-authos-field] {
116
+ display: flex;
117
+ flex-direction: column;
118
+ gap: var(--authos-spacing-xs);
119
+ }
120
+
121
+ [data-authos-field] label {
122
+ font-size: var(--authos-font-size-sm);
123
+ font-weight: 500;
124
+ color: var(--authos-color-foreground);
125
+ }
126
+
127
+ [data-authos-field] input {
128
+ width: 100%;
129
+ padding: 0.625rem 0.875rem;
130
+ font-size: var(--authos-font-size-sm);
131
+ font-family: inherit;
132
+ color: var(--authos-color-foreground);
133
+ background-color: var(--authos-color-input);
134
+ border: 1px solid var(--authos-color-input-border);
135
+ border-radius: var(--authos-border-radius);
136
+ outline: none;
137
+ transition: border-color var(--authos-transition), box-shadow var(--authos-transition);
138
+ }
139
+
140
+ [data-authos-field] input::placeholder {
141
+ color: var(--authos-color-muted);
142
+ }
143
+
144
+ [data-authos-field] input:focus {
145
+ border-color: var(--authos-color-input-focus);
146
+ box-shadow: 0 0 0 3px var(--authos-color-ring);
147
+ }
148
+
149
+ [data-authos-field] input:disabled {
150
+ opacity: 0.6;
151
+ cursor: not-allowed;
152
+ }
153
+
154
+ /* ==========================================================================
155
+ Button Styles
156
+ ========================================================================== */
157
+
158
+ [data-authos-submit] {
159
+ display: inline-flex;
160
+ align-items: center;
161
+ justify-content: center;
162
+ gap: var(--authos-spacing-sm);
163
+ width: 100%;
164
+ padding: 0.625rem 1rem;
165
+ font-size: var(--authos-font-size-sm);
166
+ font-weight: 500;
167
+ font-family: inherit;
168
+ color: var(--authos-color-primary-foreground);
169
+ background-color: var(--authos-color-primary);
170
+ border: none;
171
+ border-radius: var(--authos-border-radius);
172
+ cursor: pointer;
173
+ outline: none;
174
+ transition: background-color var(--authos-transition), box-shadow var(--authos-transition);
175
+ }
176
+
177
+ [data-authos-submit]:hover:not(:disabled) {
178
+ background-color: var(--authos-color-primary-hover);
179
+ }
180
+
181
+ [data-authos-submit]:focus-visible {
182
+ box-shadow: 0 0 0 3px var(--authos-color-ring);
183
+ }
184
+
185
+ [data-authos-submit]:disabled {
186
+ opacity: 0.6;
187
+ cursor: not-allowed;
188
+ }
189
+
190
+ [data-authos-back] {
191
+ display: inline-flex;
192
+ align-items: center;
193
+ justify-content: center;
194
+ padding: 0.5rem 1rem;
195
+ font-size: var(--authos-font-size-sm);
196
+ font-weight: 500;
197
+ font-family: inherit;
198
+ color: var(--authos-color-muted);
199
+ background: transparent;
200
+ border: none;
201
+ border-radius: var(--authos-border-radius);
202
+ cursor: pointer;
203
+ transition: color var(--authos-transition);
204
+ }
205
+
206
+ [data-authos-back]:hover {
207
+ color: var(--authos-color-foreground);
208
+ }
209
+
210
+ /* ==========================================================================
211
+ OAuth Button Styles
212
+ ========================================================================== */
213
+
214
+ [data-authos-oauth] {
215
+ display: inline-flex;
216
+ align-items: center;
217
+ justify-content: center;
218
+ gap: 0.75rem;
219
+ width: 100%;
220
+ padding: 0.625rem 1rem;
221
+ font-size: var(--authos-font-size-sm);
222
+ font-weight: 500;
223
+ font-family: var(--authos-font-family);
224
+ color: var(--authos-color-foreground);
225
+ background-color: var(--authos-color-surface);
226
+ border: 1px solid var(--authos-color-border);
227
+ border-radius: var(--authos-border-radius);
228
+ cursor: pointer;
229
+ outline: none;
230
+ transition: background-color var(--authos-transition), border-color var(--authos-transition), box-shadow var(--authos-transition);
231
+ }
232
+
233
+ [data-authos-oauth]:hover:not(:disabled) {
234
+ background-color: var(--authos-color-background);
235
+ border-color: var(--authos-color-input-border);
236
+ }
237
+
238
+ [data-authos-oauth]:focus-visible {
239
+ box-shadow: 0 0 0 3px var(--authos-color-ring);
240
+ }
241
+
242
+ [data-authos-oauth]:disabled {
243
+ opacity: 0.6;
244
+ cursor: not-allowed;
245
+ }
246
+
247
+ [data-authos-oauth] svg {
248
+ width: 1.25rem;
249
+ height: 1.25rem;
250
+ flex-shrink: 0;
251
+ }
252
+
253
+ /* ==========================================================================
254
+ Divider Styles
255
+ ========================================================================== */
256
+
257
+ [data-authos-divider] {
258
+ display: flex;
259
+ align-items: center;
260
+ gap: var(--authos-spacing-md);
261
+ margin: var(--authos-spacing-sm) 0;
262
+ }
263
+
264
+ [data-authos-divider]::before,
265
+ [data-authos-divider]::after {
266
+ content: '';
267
+ flex: 1;
268
+ height: 1px;
269
+ background-color: var(--authos-color-border);
270
+ }
271
+
272
+ [data-authos-divider] span {
273
+ font-size: var(--authos-font-size-xs);
274
+ color: var(--authos-color-muted);
275
+ text-transform: uppercase;
276
+ letter-spacing: 0.05em;
277
+ }
278
+
279
+ /* ==========================================================================
280
+ Error Styles
281
+ ========================================================================== */
282
+
283
+ [data-authos-error] {
284
+ display: flex;
285
+ align-items: center;
286
+ gap: var(--authos-spacing-sm);
287
+ padding: 0.75rem 1rem;
288
+ font-size: var(--authos-font-size-sm);
289
+ color: var(--authos-color-danger);
290
+ background-color: rgba(239, 68, 68, 0.1);
291
+ border: 1px solid rgba(239, 68, 68, 0.2);
292
+ border-radius: var(--authos-border-radius);
293
+ }
294
+
295
+ /* ==========================================================================
296
+ Link Styles
297
+ ========================================================================== */
298
+
299
+ [data-authos-link] {
300
+ font-size: var(--authos-font-size-sm);
301
+ color: var(--authos-color-primary);
302
+ text-decoration: none;
303
+ transition: color var(--authos-transition);
304
+ }
305
+
306
+ [data-authos-link]:hover {
307
+ color: var(--authos-color-primary-hover);
308
+ text-decoration: underline;
309
+ }
310
+
311
+ [data-authos-signup-prompt],
312
+ [data-authos-signin-prompt] {
313
+ text-align: center;
314
+ font-size: var(--authos-font-size-sm);
315
+ color: var(--authos-color-muted);
316
+ margin-top: var(--authos-spacing-sm);
317
+ }
318
+
319
+ /* ==========================================================================
320
+ OAuth Section
321
+ ========================================================================== */
322
+
323
+ [data-authos-oauth-section] {
324
+ display: flex;
325
+ flex-direction: column;
326
+ gap: var(--authos-spacing-sm);
327
+ }
328
+
329
+ /* ==========================================================================
330
+ User Button Styles
331
+ ========================================================================== */
332
+
333
+ [data-authos-userbutton] {
334
+ display: inline-flex;
335
+ align-items: center;
336
+ gap: var(--authos-spacing-sm);
337
+ font-family: var(--authos-font-family);
338
+ font-size: var(--authos-font-size-sm);
339
+ color: var(--authos-color-foreground);
340
+ }
341
+
342
+ [data-authos-userbutton] [data-authos-avatar] {
343
+ display: flex;
344
+ align-items: center;
345
+ justify-content: center;
346
+ width: 2rem;
347
+ height: 2rem;
348
+ font-size: var(--authos-font-size-xs);
349
+ font-weight: 600;
350
+ color: var(--authos-color-primary-foreground);
351
+ background-color: var(--authos-color-primary);
352
+ border-radius: 50%;
353
+ }
354
+
355
+ [data-authos-userbutton] [data-authos-email] {
356
+ color: var(--authos-color-foreground);
357
+ }
358
+
359
+ [data-authos-userbutton] [data-authos-logout] {
360
+ padding: 0.375rem 0.75rem;
361
+ font-size: var(--authos-font-size-xs);
362
+ font-weight: 500;
363
+ font-family: inherit;
364
+ color: var(--authos-color-muted);
365
+ background: transparent;
366
+ border: 1px solid var(--authos-color-border);
367
+ border-radius: var(--authos-border-radius-sm);
368
+ cursor: pointer;
369
+ transition: color var(--authos-transition), border-color var(--authos-transition);
370
+ }
371
+
372
+ [data-authos-userbutton] [data-authos-logout]:hover:not(:disabled) {
373
+ color: var(--authos-color-danger);
374
+ border-color: var(--authos-color-danger);
375
+ }
376
+
377
+ /* ==========================================================================
378
+ Organization Switcher Styles
379
+ ========================================================================== */
380
+
381
+ [data-authos-orgswitcher] {
382
+ font-family: var(--authos-font-family);
383
+ font-size: var(--authos-font-size-sm);
384
+ }
385
+
386
+ [data-authos-orgswitcher] select {
387
+ padding: 0.5rem 2rem 0.5rem 0.75rem;
388
+ font-size: var(--authos-font-size-sm);
389
+ font-family: inherit;
390
+ color: var(--authos-color-foreground);
391
+ background-color: var(--authos-color-input);
392
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
393
+ background-repeat: no-repeat;
394
+ background-position: right 0.5rem center;
395
+ border: 1px solid var(--authos-color-input-border);
396
+ border-radius: var(--authos-border-radius);
397
+ cursor: pointer;
398
+ outline: none;
399
+ appearance: none;
400
+ -webkit-appearance: none;
401
+ -moz-appearance: none;
402
+ transition: border-color var(--authos-transition), box-shadow var(--authos-transition);
403
+ }
404
+
405
+ [data-authos-orgswitcher] select:focus {
406
+ border-color: var(--authos-color-input-focus);
407
+ box-shadow: 0 0 0 3px var(--authos-color-ring);
408
+ }
409
+
410
+ [data-authos-orgswitcher] select:disabled {
411
+ opacity: 0.6;
412
+ cursor: not-allowed;
413
+ }
414
+
415
+ /* ==========================================================================
416
+ Loading State
417
+ ========================================================================== */
418
+
419
+ [data-state="loading"] {
420
+ opacity: 0.6;
421
+ }
422
+ `;
423
+ var stylesInjected = false;
424
+ function injectStyles() {
425
+ if (stylesInjected) return;
426
+ if (typeof document === "undefined") return;
427
+ const styleElement = document.createElement("style");
428
+ styleElement.setAttribute("data-authos-styles", "");
429
+ styleElement.textContent = AUTHOS_STYLES;
430
+ document.head.appendChild(styleElement);
431
+ stylesInjected = true;
432
+ }
433
+ function applyVariables(variables) {
434
+ if (typeof document === "undefined") return;
435
+ const root = document.documentElement;
436
+ for (const [key, value] of Object.entries(variables)) {
437
+ const cssVar = `--authos-${key.replace(/([A-Z])/g, "-$1").toLowerCase()}`;
438
+ root.style.setProperty(cssVar, value);
439
+ }
440
+ }
441
+
442
+ // src/plugin.ts
8
443
  function createAuthOS(options) {
9
444
  const getStorage = () => {
10
445
  if (options.storage) return options.storage;
@@ -44,6 +479,10 @@ function createAuthOS(options) {
44
479
  };
45
480
  return {
46
481
  install(app) {
482
+ injectStyles();
483
+ if (options.appearance?.variables) {
484
+ applyVariables(options.appearance.variables);
485
+ }
47
486
  nextTick(() => {
48
487
  setInitialToken();
49
488
  });
@@ -251,7 +690,7 @@ var SignIn = defineComponent({
251
690
  },
252
691
  emits: ["success", "error"],
253
692
  setup(props, { slots, emit }) {
254
- const { client } = useAuthOS();
693
+ const { client, options } = useAuthOS();
255
694
  const email = ref("");
256
695
  const password = ref("");
257
696
  const mfaCode = ref("");
@@ -266,7 +705,9 @@ var SignIn = defineComponent({
266
705
  if (step.value === "credentials") {
267
706
  const result = await client.auth.login({
268
707
  email: email.value,
269
- password: password.value
708
+ password: password.value,
709
+ org_slug: options.org,
710
+ service_slug: options.service
270
711
  });
271
712
  if (result.expires_in === MFA_PREAUTH_EXPIRY) {
272
713
  preauthToken.value = result.access_token;
@@ -306,31 +747,83 @@ var SignIn = defineComponent({
306
747
  if (slots.default) {
307
748
  return slots.default(slotProps);
308
749
  }
309
- return h("form", { onSubmit: (e) => {
310
- e.preventDefault();
311
- submit();
312
- } }, [
313
- step.value === "credentials" ? [
314
- h("input", {
315
- type: "email",
316
- value: email.value,
317
- placeholder: "Email",
318
- onInput: (e) => email.value = e.target.value
319
- }),
320
- h("input", {
321
- type: "password",
322
- value: password.value,
323
- placeholder: "Password",
324
- onInput: (e) => password.value = e.target.value
325
- })
326
- ] : h("input", {
327
- type: "text",
328
- value: mfaCode.value,
329
- placeholder: "MFA Code",
330
- onInput: (e) => mfaCode.value = e.target.value
331
- }),
332
- error.value && h("p", { style: "color: red" }, error.value),
333
- h("button", { type: "submit", disabled: isSubmitting.value }, isSubmitting.value ? "Signing in..." : "Sign In")
750
+ if (step.value === "mfa") {
751
+ return h("div", { "data-authos-signin": "", "data-state": "mfa" }, [
752
+ h("form", { onSubmit: (e) => {
753
+ e.preventDefault();
754
+ submit();
755
+ } }, [
756
+ h("div", { "data-authos-field": "mfa-code" }, [
757
+ h("label", { for: "authos-mfa-code" }, "Verification Code"),
758
+ h("input", {
759
+ id: "authos-mfa-code",
760
+ type: "text",
761
+ inputMode: "numeric",
762
+ autocomplete: "one-time-code",
763
+ value: mfaCode.value,
764
+ placeholder: "Enter 6-digit code",
765
+ required: true,
766
+ disabled: isSubmitting.value,
767
+ onInput: (e) => mfaCode.value = e.target.value
768
+ })
769
+ ]),
770
+ error.value && h("div", { "data-authos-error": "" }, error.value),
771
+ h("button", {
772
+ type: "submit",
773
+ disabled: isSubmitting.value,
774
+ "data-authos-submit": ""
775
+ }, isSubmitting.value ? "Verifying..." : "Verify"),
776
+ h("button", {
777
+ type: "button",
778
+ "data-authos-back": "",
779
+ onClick: () => {
780
+ step.value = "credentials";
781
+ mfaCode.value = "";
782
+ preauthToken.value = "";
783
+ error.value = null;
784
+ }
785
+ }, "Back to login")
786
+ ])
787
+ ]);
788
+ }
789
+ return h("div", { "data-authos-signin": "", "data-state": "credentials" }, [
790
+ h("form", { onSubmit: (e) => {
791
+ e.preventDefault();
792
+ submit();
793
+ } }, [
794
+ h("div", { "data-authos-field": "email" }, [
795
+ h("label", { for: "authos-email" }, "Email"),
796
+ h("input", {
797
+ id: "authos-email",
798
+ type: "email",
799
+ autocomplete: "email",
800
+ value: email.value,
801
+ placeholder: "Enter your email",
802
+ required: true,
803
+ disabled: isSubmitting.value,
804
+ onInput: (e) => email.value = e.target.value
805
+ })
806
+ ]),
807
+ h("div", { "data-authos-field": "password" }, [
808
+ h("label", { for: "authos-password" }, "Password"),
809
+ h("input", {
810
+ id: "authos-password",
811
+ type: "password",
812
+ autocomplete: "current-password",
813
+ value: password.value,
814
+ placeholder: "Enter your password",
815
+ required: true,
816
+ disabled: isSubmitting.value,
817
+ onInput: (e) => password.value = e.target.value
818
+ })
819
+ ]),
820
+ error.value && h("div", { "data-authos-error": "" }, error.value),
821
+ h("button", {
822
+ type: "submit",
823
+ disabled: isSubmitting.value,
824
+ "data-authos-submit": ""
825
+ }, isSubmitting.value ? "Signing in..." : "Sign In")
826
+ ])
334
827
  ]);
335
828
  };
336
829
  }
@@ -345,6 +838,16 @@ var SignUp = defineComponent({
345
838
  onError: {
346
839
  type: Function,
347
840
  default: void 0
841
+ },
842
+ /** Organization slug for tenant context */
843
+ orgSlug: {
844
+ type: String,
845
+ default: void 0
846
+ },
847
+ /** Service slug for tenant attribution (used with orgSlug) */
848
+ serviceSlug: {
849
+ type: String,
850
+ default: void 0
348
851
  }
349
852
  },
350
853
  emits: ["success", "error"],
@@ -360,7 +863,9 @@ var SignUp = defineComponent({
360
863
  try {
361
864
  await client.auth.register({
362
865
  email: email.value,
363
- password: password.value
866
+ password: password.value,
867
+ org_slug: props.orgSlug,
868
+ service_slug: props.serviceSlug
364
869
  });
365
870
  emit("success");
366
871
  props.onSuccess?.();
@@ -387,24 +892,44 @@ var SignUp = defineComponent({
387
892
  if (slots.default) {
388
893
  return slots.default(slotProps);
389
894
  }
390
- return h("form", { onSubmit: (e) => {
391
- e.preventDefault();
392
- submit();
393
- } }, [
394
- h("input", {
395
- type: "email",
396
- value: email.value,
397
- placeholder: "Email",
398
- onInput: (e) => email.value = e.target.value
399
- }),
400
- h("input", {
401
- type: "password",
402
- value: password.value,
403
- placeholder: "Password",
404
- onInput: (e) => password.value = e.target.value
405
- }),
406
- error.value && h("p", { style: "color: red" }, error.value),
407
- h("button", { type: "submit", disabled: isSubmitting.value }, isSubmitting.value ? "Creating account..." : "Sign Up")
895
+ return h("div", { "data-authos-signup": "", "data-state": "credentials" }, [
896
+ h("form", { onSubmit: (e) => {
897
+ e.preventDefault();
898
+ submit();
899
+ } }, [
900
+ h("div", { "data-authos-field": "email" }, [
901
+ h("label", { for: "authos-signup-email" }, "Email"),
902
+ h("input", {
903
+ id: "authos-signup-email",
904
+ type: "email",
905
+ autocomplete: "email",
906
+ value: email.value,
907
+ placeholder: "Enter your email",
908
+ required: true,
909
+ disabled: isSubmitting.value,
910
+ onInput: (e) => email.value = e.target.value
911
+ })
912
+ ]),
913
+ h("div", { "data-authos-field": "password" }, [
914
+ h("label", { for: "authos-signup-password" }, "Password"),
915
+ h("input", {
916
+ id: "authos-signup-password",
917
+ type: "password",
918
+ autocomplete: "new-password",
919
+ value: password.value,
920
+ placeholder: "Create a password",
921
+ required: true,
922
+ disabled: isSubmitting.value,
923
+ onInput: (e) => password.value = e.target.value
924
+ })
925
+ ]),
926
+ error.value && h("div", { "data-authos-error": "" }, error.value),
927
+ h("button", {
928
+ type: "submit",
929
+ disabled: isSubmitting.value,
930
+ "data-authos-submit": ""
931
+ }, isSubmitting.value ? "Creating account..." : "Sign Up")
932
+ ])
408
933
  ]);
409
934
  };
410
935
  }
@@ -495,11 +1020,17 @@ var UserButton = defineComponent({
495
1020
  if (!user.value) {
496
1021
  return h("div", { "data-authos-userbutton": "", "data-state": "signed-out" }, "Not signed in");
497
1022
  }
498
- return h("div", { "data-authos-userbutton": "", "data-state": "signed-in", style: "display: flex; align-items: center; gap: 8px;" }, [
499
- h("span", user.value.email),
1023
+ const getInitials = (email) => {
1024
+ const name = email.split("@")[0];
1025
+ return name.substring(0, 2).toUpperCase();
1026
+ };
1027
+ return h("div", { "data-authos-userbutton": "", "data-state": "signed-in" }, [
1028
+ h("div", { "data-authos-avatar": "" }, getInitials(user.value.email)),
1029
+ h("span", { "data-authos-email": "" }, user.value.email),
500
1030
  h(
501
1031
  "button",
502
1032
  {
1033
+ "data-authos-logout": "",
503
1034
  onClick: logout,
504
1035
  disabled: isLoggingOut.value
505
1036
  },
@@ -570,6 +1101,55 @@ var PROVIDER_NAMES = {
570
1101
  google: "Google",
571
1102
  microsoft: "Microsoft"
572
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
+ }
573
1153
  var OAuthButton = defineComponent({
574
1154
  name: "OAuthButton",
575
1155
  props: {
@@ -633,7 +1213,10 @@ See: https://docs.authos.dev/vue/oauth-setup`
633
1213
  "data-authos-oauth": "",
634
1214
  "data-provider": props.provider
635
1215
  },
636
- `Continue with ${providerName.value}`
1216
+ [
1217
+ getProviderIcon(props.provider),
1218
+ h("span", `Continue with ${providerName.value}`)
1219
+ ]
637
1220
  );
638
1221
  };
639
1222
  }