@autenticar-me/vue 0.1.0 → 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.
Files changed (84) hide show
  1. package/dist/components/AuthSwitcher.vue.d.ts +2 -2
  2. package/dist/components/AuthSwitcher.vue.d.ts.map +1 -0
  3. package/dist/components/Buttons/SignInButton.vue.d.ts +2 -2
  4. package/dist/components/Buttons/SignInButton.vue.d.ts.map +1 -0
  5. package/dist/components/Buttons/SignOutButton.vue.d.ts +2 -2
  6. package/dist/components/Buttons/SignOutButton.vue.d.ts.map +1 -0
  7. package/dist/components/Buttons/SignUpButton.vue.d.ts +2 -2
  8. package/dist/components/Buttons/SignUpButton.vue.d.ts.map +1 -0
  9. package/dist/components/Layout/SignedIn.vue.d.ts +12 -7
  10. package/dist/components/Layout/SignedIn.vue.d.ts.map +1 -0
  11. package/dist/components/Layout/SignedOut.vue.d.ts +12 -7
  12. package/dist/components/Layout/SignedOut.vue.d.ts.map +1 -0
  13. package/dist/components/Modals/Modal.vue.d.ts +15 -10
  14. package/dist/components/Modals/Modal.vue.d.ts.map +1 -0
  15. package/dist/components/Modals/SignInModal.vue.d.ts +4 -4
  16. package/dist/components/Modals/SignInModal.vue.d.ts.map +1 -0
  17. package/dist/components/Modals/SignUpModal.vue.d.ts +4 -4
  18. package/dist/components/Modals/SignUpModal.vue.d.ts.map +1 -0
  19. package/dist/components/Notification.vue.d.ts +3 -3
  20. package/dist/components/Notification.vue.d.ts.map +1 -0
  21. package/dist/components/SignIn.vue.d.ts +7 -4
  22. package/dist/components/SignIn.vue.d.ts.map +1 -0
  23. package/dist/components/SignUp.vue.d.ts +7 -4
  24. package/dist/components/SignUp.vue.d.ts.map +1 -0
  25. package/dist/components/UserProfile.vue.d.ts +4 -2
  26. package/dist/components/UserProfile.vue.d.ts.map +1 -0
  27. package/dist/composables/useAtm.d.ts +5 -4
  28. package/dist/composables/useAtm.d.ts.map +1 -0
  29. package/dist/composables/useAtmClient.d.ts +2 -1
  30. package/dist/composables/useAtmClient.d.ts.map +1 -0
  31. package/dist/composables/useAuth.d.ts +3 -2
  32. package/dist/composables/useAuth.d.ts.map +1 -0
  33. package/dist/index.cjs +2270 -0
  34. package/dist/index.cjs.map +1 -0
  35. package/dist/index.d.ts +18 -16
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +2269 -31
  38. package/dist/index.js.map +1 -0
  39. package/dist/plugin.d.ts +2 -1
  40. package/dist/plugin.d.ts.map +1 -0
  41. package/dist/types/configurations.type.d.ts +10 -0
  42. package/dist/types/configurations.type.d.ts.map +1 -0
  43. package/dist/types/session.type.d.ts +1 -0
  44. package/dist/types/session.type.d.ts.map +1 -0
  45. package/dist/types/user-attribute.type.d.ts +1 -0
  46. package/dist/types/user-attribute.type.d.ts.map +1 -0
  47. package/dist/types/user.type.d.ts +2 -1
  48. package/dist/types/user.type.d.ts.map +1 -0
  49. package/dist/utils/device.d.ts +2 -1
  50. package/dist/utils/device.d.ts.map +1 -0
  51. package/dist/utils/fetch-configurations.d.ts +3 -2
  52. package/dist/utils/fetch-configurations.d.ts.map +1 -0
  53. package/dist/utils/fetch-user.d.ts +3 -2
  54. package/dist/utils/fetch-user.d.ts.map +1 -0
  55. package/dist/utils/tokens.d.ts +1 -0
  56. package/dist/utils/tokens.d.ts.map +1 -0
  57. package/dist/vue.css +1761 -0
  58. package/package.json +29 -5
  59. package/.claude/settings.local.json +0 -7
  60. package/dist/components/AuthSwitcher.vue.js +0 -76
  61. package/dist/components/Buttons/SignInButton.vue.js +0 -110
  62. package/dist/components/Buttons/SignOutButton.vue.js +0 -68
  63. package/dist/components/Buttons/SignUpButton.vue.js +0 -86
  64. package/dist/components/Layout/SignedIn.vue.js +0 -54
  65. package/dist/components/Layout/SignedOut.vue.js +0 -54
  66. package/dist/components/Modals/Modal.vue.js +0 -133
  67. package/dist/components/Modals/SignInModal.vue.js +0 -149
  68. package/dist/components/Modals/SignUpModal.vue.js +0 -165
  69. package/dist/components/Notification.vue.js +0 -95
  70. package/dist/components/SignIn.vue.js +0 -485
  71. package/dist/components/SignUp.vue.js +0 -339
  72. package/dist/components/UserProfile.vue.js +0 -916
  73. package/dist/composables/useAtm.js +0 -11
  74. package/dist/composables/useAtmClient.js +0 -8
  75. package/dist/composables/useAuth.js +0 -38
  76. package/dist/plugin.js +0 -33
  77. package/dist/types/configurations.type.js +0 -2
  78. package/dist/types/session.type.js +0 -2
  79. package/dist/types/user-attribute.type.js +0 -2
  80. package/dist/types/user.type.js +0 -2
  81. package/dist/utils/device.js +0 -46
  82. package/dist/utils/fetch-configurations.js +0 -45
  83. package/dist/utils/fetch-user.js +0 -36
  84. package/dist/utils/tokens.js +0 -46
package/dist/index.js CHANGED
@@ -1,32 +1,2270 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
1
+ import { inject, defineComponent, createElementBlock, openBlock, createElementVNode, normalizeStyle, createCommentVNode, toDisplayString, renderSlot, useCssVars, computed, ref, onMounted, nextTick, watch, unref, withModifiers, withDirectives, vModelText, Fragment, renderList, createTextVNode, createBlock, Teleport, createVNode, Transition, withCtx, normalizeClass, onUnmounted, provide } from "vue";
2
+ import UniversalCookie from "universal-cookie";
3
+ import { AtmClient } from "@autenticar-me/client-js";
4
+ const writeAccessTokenInCookie = (accessToken) => {
5
+ const cookies = new UniversalCookie();
6
+ if (accessToken === null) {
7
+ cookies.remove("atm_access_token");
8
+ } else {
9
+ cookies.set("atm_access_token", accessToken);
10
+ }
11
+ };
12
+ const getAccessToken = async () => {
13
+ const cookies = new UniversalCookie();
14
+ return cookies.get("atm_access_token");
15
+ };
16
+ const writeRefreshTokenInCookie = (refreshToken) => {
17
+ const cookies = new UniversalCookie();
18
+ if (refreshToken === null) {
19
+ cookies.remove("atm_refresh_token");
20
+ } else {
21
+ cookies.set("atm_refresh_token", refreshToken);
22
+ }
23
+ };
24
+ const fetchUser = async (client, user) => {
25
+ let accessToken = await getAccessToken();
26
+ if (accessToken == null) {
27
+ user.value = null;
28
+ return;
29
+ }
30
+ const response = await client.value.account(accessToken).getProfile();
31
+ user.value = {
32
+ id: response.id,
33
+ username: response.username,
34
+ firstName: response.first_name,
35
+ lastName: response.last_name,
36
+ primaryEmailAddress: response.primary_email_address,
37
+ primaryEmailAddressId: response.primary_email_address_id,
38
+ profileImage: response.profile_image,
39
+ attributes: response.attributes.map((atribute) => ({
40
+ key: atribute.key,
41
+ mode: atribute.mode,
42
+ value: atribute.value
43
+ }))
44
+ };
45
+ };
46
+ function useAtm() {
47
+ const ctx = inject("atm");
48
+ if (!ctx) {
49
+ throw new Error("[Autenticar.me] É necessário configurar o plugin no main.ts");
50
+ }
51
+ return ctx;
52
+ }
53
+ function useAuth() {
54
+ const { client, user } = useAtm();
55
+ const signInByAccessToken = async (accessToken) => {
56
+ writeAccessTokenInCookie(accessToken);
57
+ await fetchUser(client, user);
58
+ };
59
+ const logout = async () => {
60
+ const accessToken = await getAccessToken();
61
+ if (accessToken == null) {
62
+ return;
63
+ }
64
+ await client.value.account(accessToken).logout();
65
+ user.value = null;
66
+ writeAccessTokenInCookie(null);
67
+ };
68
+ return {
69
+ user,
70
+ signInByAccessToken,
71
+ getAccessToken,
72
+ fetchUser,
73
+ logout
74
+ };
75
+ }
76
+ const _hoisted_1$8 = { class: "atm-overlay" };
77
+ const _hoisted_2$3 = { class: "atm-modal" };
78
+ const _hoisted_3$3 = { class: "atm-modal-content" };
79
+ const _hoisted_4$3 = {
80
+ key: 0,
81
+ class: "atm-modal-title"
82
+ };
83
+ const _sfc_main$c = /* @__PURE__ */ defineComponent({
84
+ __name: "Modal",
85
+ props: {
86
+ title: {
87
+ type: String,
88
+ required: false,
89
+ default: null
90
+ },
91
+ maxWidth: {
92
+ type: Number,
93
+ required: false,
94
+ default: 672
95
+ }
96
+ },
97
+ emits: [
98
+ "close"
99
+ ],
100
+ setup(__props, { emit: __emit }) {
101
+ const emit = __emit;
102
+ const close = () => {
103
+ emit("close");
104
+ };
105
+ return (_ctx, _cache) => {
106
+ return openBlock(), createElementBlock("div", _hoisted_1$8, [
107
+ createElementVNode("div", {
108
+ class: "atm-container",
109
+ style: normalizeStyle({ maxWidth: `${__props.maxWidth}px` })
110
+ }, [
111
+ _cache[2] || (_cache[2] = createElementVNode("div", { class: "atm-fade-layer" }, [
112
+ createElementVNode("div", { class: "atm-fade-bg" })
113
+ ], -1)),
114
+ createElementVNode("div", _hoisted_2$3, [
115
+ createElementVNode("button", {
116
+ class: "atm-close-button",
117
+ onClick: _cache[0] || (_cache[0] = ($event) => close())
118
+ }, [..._cache[1] || (_cache[1] = [
119
+ createElementVNode("svg", {
120
+ class: "atm-icon",
121
+ fill: "none",
122
+ stroke: "currentColor",
123
+ viewBox: "0 0 24 24"
124
+ }, [
125
+ createElementVNode("path", {
126
+ "stroke-linecap": "round",
127
+ "stroke-linejoin": "round",
128
+ "stroke-width": "2",
129
+ d: "M6 18L18 6M6 6l12 12"
130
+ })
131
+ ], -1)
132
+ ])]),
133
+ createElementVNode("div", _hoisted_3$3, [
134
+ __props.title ? (openBlock(), createElementBlock("h3", _hoisted_4$3, toDisplayString(__props.title), 1)) : createCommentVNode("", true),
135
+ createElementVNode("div", null, [
136
+ renderSlot(_ctx.$slots, "default", {}, void 0, true)
137
+ ])
138
+ ])
139
+ ])
140
+ ], 4)
141
+ ]);
142
+ };
143
+ }
144
+ });
145
+ const _export_sfc = (sfc, props) => {
146
+ const target = sfc.__vccOpts || sfc;
147
+ for (const [key, val] of props) {
148
+ target[key] = val;
149
+ }
150
+ return target;
151
+ };
152
+ const Modal = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["__scopeId", "data-v-c347df44"]]);
153
+ function useAtmClient() {
154
+ const { client } = useAtm();
155
+ return client.value;
156
+ }
157
+ const DEVICE_TOKEN_KEY = "atm_device_token";
158
+ const getDeviceToken = async (client) => {
159
+ try {
160
+ const storedToken = localStorage.getItem(DEVICE_TOKEN_KEY);
161
+ if (storedToken) {
162
+ return storedToken;
163
+ }
164
+ const response = await fetch(`${client.getProjectUrl()}/api/v1/devices`, {
165
+ method: "POST",
166
+ headers: {
167
+ "accept": "application/json",
168
+ "x-public-key": client.getPublicKey()
169
+ }
170
+ });
171
+ if (!response.ok) {
172
+ const errorBody = await response.json();
173
+ throw new Error(errorBody.message || "Falha ao criar o token do dispositivo.");
174
+ }
175
+ const data = await response.json();
176
+ if (!data.token) {
177
+ throw new Error("O token do dispositivo não foi retornado pelo servidor.");
178
+ }
179
+ localStorage.setItem(DEVICE_TOKEN_KEY, data.token);
180
+ return data.token;
181
+ } catch (error) {
182
+ throw error;
183
+ }
184
+ };
185
+ const _hoisted_1$7 = { class: "atm-login-container" };
186
+ const _hoisted_2$2 = { class: "atm-logo-container" };
187
+ const _hoisted_3$2 = ["src"];
188
+ const _hoisted_4$2 = {
189
+ key: 1,
190
+ class: "atm-logo-placeholder"
191
+ };
192
+ const _hoisted_5$2 = { class: "atm-project-name" };
193
+ const _hoisted_6$2 = { key: 0 };
194
+ const _hoisted_7$2 = {
195
+ key: 0,
196
+ class: "atm-form-group"
197
+ };
198
+ const _hoisted_8$2 = { class: "atm-input-label" };
199
+ const _hoisted_9$2 = ["placeholder", "disabled"];
200
+ const _hoisted_10$2 = {
201
+ key: 0,
202
+ class: "atm-field-error"
203
+ };
204
+ const _hoisted_11$2 = {
205
+ key: 1,
206
+ class: "atm-form-group"
207
+ };
208
+ const _hoisted_12$2 = ["disabled"];
209
+ const _hoisted_13$2 = {
210
+ key: 0,
211
+ class: "atm-field-error"
212
+ };
213
+ const _hoisted_14$2 = {
214
+ class: "atm-alternative-options",
215
+ style: { "margin-top": "4px" }
216
+ };
217
+ const _hoisted_15$2 = ["disabled"];
218
+ const _hoisted_16$2 = {
219
+ key: 2,
220
+ class: "atm-strategy-choice"
221
+ };
222
+ const _hoisted_17$2 = { class: "atm-strategy-buttons" };
223
+ const _hoisted_18$2 = ["onClick", "disabled"];
224
+ const _hoisted_19$2 = { key: 0 };
225
+ const _hoisted_20$2 = {
226
+ key: 3,
227
+ class: "atm-form-group"
228
+ };
229
+ const _hoisted_21$2 = {
230
+ key: 1,
231
+ class: "atm-forgot-password-message",
232
+ style: { "text-align": "center", "color": "#333", "margin-bottom": "16px" }
233
+ };
234
+ const _hoisted_22$2 = ["disabled"];
235
+ const _hoisted_23$2 = { key: 0 };
236
+ const _hoisted_24$2 = {
237
+ key: 1,
238
+ class: "button-spinner"
239
+ };
240
+ const _hoisted_25$2 = { key: 0 };
241
+ const _hoisted_26$2 = { key: 1 };
242
+ const _hoisted_27$2 = { class: "atm-footer-links" };
243
+ const _hoisted_28$1 = { class: "atm-signup-text" };
244
+ const _sfc_main$b = /* @__PURE__ */ defineComponent({
245
+ __name: "SignIn",
246
+ emits: [
247
+ "completed",
248
+ "sign-up"
249
+ ],
250
+ setup(__props, { emit: __emit }) {
251
+ useCssVars((_ctx) => ({
252
+ "e2d4c99e": atmPrimaryColor.value,
253
+ "v182122ff": atmSecondaryColor.value
254
+ }));
255
+ const emit = __emit;
256
+ const showNotification = inject("showNotification");
257
+ const form = ref({
258
+ emailAddress: "",
259
+ password: ""
260
+ });
261
+ const currentStep = ref("email");
262
+ const signInStep = ref(null);
263
+ const availableStrategies = ref([]);
264
+ const selectedStrategy = ref(null);
265
+ const serverStep = ref(null);
266
+ const isLoading = ref(false);
267
+ const emailInput = ref(null);
268
+ const passwordInput = ref(null);
269
+ const fieldErrors = ref({
270
+ emailAddress: [],
271
+ password: []
272
+ });
273
+ const client = useAtmClient();
274
+ const { signInByAccessToken } = useAuth();
275
+ const { configurations } = useAtm();
276
+ const atmPrimaryColor = computed(() => configurations.value?.design?.primaryColor);
277
+ const atmSecondaryColor = computed(() => configurations.value?.design?.secondaryColor);
278
+ const logoUrl = computed(() => configurations.value?.project?.logo || "");
279
+ const buttonText = computed(() => {
280
+ if (currentStep.value === "email") return "Entrar";
281
+ if (currentStep.value === "choose_strategy") return "";
282
+ if (currentStep.value === "forgot_password_message") return "";
283
+ return "Finalizar";
284
+ });
285
+ const showEmailField = computed(() => currentStep.value === "email" || currentStep.value === "forgot_password_message");
286
+ const showPasswordField = computed(() => currentStep.value === "password");
287
+ const showStrategyChoice = computed(() => currentStep.value === "choose_strategy");
288
+ const labelText = computed(() => {
289
+ if (configurations.value?.username?.enable === false) {
290
+ return "Email";
291
+ }
292
+ return "Email ou Nome de usuário";
293
+ });
294
+ const inputPlaceholder = computed(() => {
295
+ if (configurations.value?.username?.enable === false) {
296
+ return "email@exemplo.com";
297
+ }
298
+ return "email@exemplo.com ou seu username";
299
+ });
300
+ const processAvailableStrategies = (stepData) => {
301
+ const strategies = stepData?.supported?.first_factors || [];
302
+ return {
303
+ password: strategies.find((s) => s.strategy === "password"),
304
+ emailLink: strategies.find((s) => s.strategy === "email_link")
305
+ };
306
+ };
307
+ const clearErrors = () => {
308
+ fieldErrors.value = {
309
+ emailAddress: [],
310
+ password: []
311
+ };
312
+ };
313
+ const handleEmailStep = async () => {
314
+ if (!form.value.emailAddress.trim()) {
315
+ showNotification?.("Email ou nome de usuário é obrigatório");
316
+ return false;
317
+ }
318
+ try {
319
+ const deviceToken = await getDeviceToken(client);
320
+ const stepData = await client.auth().signInByEmailAddress(form.value.emailAddress, deviceToken);
321
+ signInStep.value = stepData;
322
+ serverStep.value = stepData.step;
323
+ const strategies = processAvailableStrategies(stepData);
324
+ if (strategies.password) {
325
+ selectedStrategy.value = strategies.password;
326
+ currentStep.value = "password";
327
+ } else if (strategies.emailLink) {
328
+ availableStrategies.value = [strategies.emailLink].filter(Boolean);
329
+ currentStep.value = "choose_strategy";
330
+ } else {
331
+ showNotification?.("Nenhum método de autenticação disponível");
332
+ return false;
333
+ }
334
+ return true;
335
+ } catch (error) {
336
+ if (error.errors && typeof error.errors === "object") {
337
+ if (error.errors.email_address) {
338
+ fieldErrors.value.emailAddress = error.errors.email_address;
339
+ }
340
+ } else {
341
+ showNotification?.(error.message || "Erro ao verificar email");
342
+ }
343
+ return false;
344
+ }
345
+ };
346
+ const selectStrategy = (strategy) => {
347
+ selectedStrategy.value = strategy;
348
+ currentStep.value = strategy.strategy;
349
+ if (strategy.strategy === "email_link") {
350
+ handleEmailLinkStep();
351
+ }
352
+ };
353
+ const handlePasswordStep = async () => {
354
+ if (!form.value.password.trim()) {
355
+ showNotification?.("Senha é obrigatória");
356
+ return false;
357
+ }
358
+ try {
359
+ if (!signInStep.value) {
360
+ showNotification?.("Estado de autenticação inválido");
361
+ return false;
362
+ }
363
+ if (serverStep.value !== "first_factor") {
364
+ showNotification?.("Etapa inválida para autenticação com senha");
365
+ return false;
366
+ }
367
+ const attemptToken = signInStep.value.sign_in_attempt_token;
368
+ if (!attemptToken) {
369
+ showNotification?.("Token de tentativa não encontrado");
370
+ return false;
371
+ }
372
+ const response = await client.auth().authenticateWithPassword(signInStep.value.id, attemptToken, form.value.password);
373
+ if (response?.step) {
374
+ serverStep.value = response.step;
375
+ signInStep.value = { ...signInStep.value, ...response };
376
+ }
377
+ return true;
378
+ } catch (error) {
379
+ if (error.errors && typeof error.errors === "object") {
380
+ if (error.errors.password) {
381
+ fieldErrors.value.password = error.errors.password;
382
+ }
383
+ } else {
384
+ showNotification?.(error.message || "Senha incorreta");
385
+ }
386
+ return false;
387
+ }
388
+ };
389
+ const handleEmailLinkStep = async () => {
390
+ try {
391
+ await client.auth().sendEmailLink(signInStep.value.id, selectedStrategy.value?.email_address_id);
392
+ showNotification?.("Link de verificação enviado para seu email", "success");
393
+ return true;
394
+ } catch (error) {
395
+ showNotification?.(error.message || "Erro ao enviar link de verificação");
396
+ return false;
397
+ }
398
+ };
399
+ const sendResetPasswordLink = async () => {
400
+ if (!form.value.emailAddress.trim()) {
401
+ showNotification?.("Informe o email para enviar o link de recuperação");
402
+ return;
403
+ }
404
+ try {
405
+ await client.auth().resetPassword({ email_address: form.value.emailAddress });
406
+ currentStep.value = "forgot_password_message";
407
+ } catch (error) {
408
+ showNotification?.(error.message || "Erro ao solicitar recuperação de senha");
409
+ }
410
+ };
411
+ const completeAuthentication = async () => {
412
+ try {
413
+ const attemptToken = signInStep.value.sign_in_attempt_token;
414
+ if (!attemptToken) {
415
+ showNotification?.("Token de tentativa não encontrado");
416
+ isLoading.value = false;
417
+ return;
418
+ }
419
+ const tokens = await client.auth().generateTokens(signInStep.value.id, attemptToken);
420
+ signInByAccessToken(tokens.access_token);
421
+ writeRefreshTokenInCookie(tokens.refresh_token);
422
+ showNotification?.("Login realizado com sucesso!", "success");
423
+ setTimeout(() => {
424
+ emit("completed");
425
+ }, 1e3);
426
+ } catch (error) {
427
+ showNotification?.(error.message || "Erro ao finalizar autenticação");
428
+ isLoading.value = false;
429
+ }
430
+ };
431
+ const submit = async () => {
432
+ if (isLoading.value) return;
433
+ clearErrors();
434
+ try {
435
+ isLoading.value = true;
436
+ let stepSuccess = false;
437
+ let shouldCompleteAuth = false;
438
+ if (currentStep.value === "email") {
439
+ stepSuccess = await handleEmailStep();
440
+ if (stepSuccess) {
441
+ isLoading.value = false;
442
+ }
443
+ } else if (currentStep.value === "password") {
444
+ stepSuccess = await handlePasswordStep();
445
+ if (stepSuccess) {
446
+ shouldCompleteAuth = true;
447
+ }
448
+ } else if (currentStep.value === "choose_strategy") {
449
+ return;
450
+ } else if (currentStep.value === "email_link") {
451
+ return;
452
+ } else if (currentStep.value === "forgot_password_message") {
453
+ return;
454
+ }
455
+ if (shouldCompleteAuth) {
456
+ await completeAuthentication();
457
+ } else if (!stepSuccess) {
458
+ isLoading.value = false;
459
+ }
460
+ } catch (error) {
461
+ if (error.errors && typeof error.errors === "object") {
462
+ const mappedErrors = {};
463
+ if (error.errors.email_address) {
464
+ mappedErrors.emailAddress = error.errors.email_address;
465
+ }
466
+ if (error.errors.password) {
467
+ mappedErrors.password = error.errors.password;
468
+ }
469
+ fieldErrors.value = { ...fieldErrors.value, ...mappedErrors };
470
+ } else {
471
+ showNotification?.(error.message || "Erro durante o processo de login");
472
+ }
473
+ isLoading.value = false;
474
+ }
475
+ };
476
+ const signUp = () => emit("sign-up");
477
+ onMounted(() => {
478
+ nextTick(() => {
479
+ if (emailInput.value) {
480
+ emailInput.value.focus();
481
+ }
482
+ });
483
+ });
484
+ watch(currentStep, (newStep) => {
485
+ nextTick(() => {
486
+ if (newStep === "password" && passwordInput.value) {
487
+ passwordInput.value.focus();
488
+ }
489
+ });
490
+ });
491
+ return (_ctx, _cache) => {
492
+ return unref(configurations) ? (openBlock(), createElementBlock("form", {
493
+ key: 0,
494
+ onSubmit: _cache[4] || (_cache[4] = withModifiers(($event) => submit(), ["prevent"]))
495
+ }, [
496
+ createElementVNode("div", _hoisted_1$7, [
497
+ createElementVNode("div", _hoisted_2$2, [
498
+ logoUrl.value ? (openBlock(), createElementBlock("img", {
499
+ key: 0,
500
+ src: logoUrl.value,
501
+ alt: "Logo",
502
+ class: "atm-logo-image"
503
+ }, null, 8, _hoisted_3$2)) : (openBlock(), createElementBlock("div", _hoisted_4$2, "Logo"))
504
+ ]),
505
+ createElementVNode("h2", _hoisted_5$2, toDisplayString(unref(configurations).project.name), 1),
506
+ _cache[13] || (_cache[13] = createElementVNode("p", { class: "atm-welcome-text" }, "Bem-vindo de volta! Faça login para continuar", -1)),
507
+ currentStep.value !== "forgot_password_message" ? (openBlock(), createElementBlock("div", _hoisted_6$2, [
508
+ showEmailField.value ? (openBlock(), createElementBlock("div", _hoisted_7$2, [
509
+ createElementVNode("label", _hoisted_8$2, toDisplayString(labelText.value), 1),
510
+ withDirectives(createElementVNode("input", {
511
+ ref_key: "emailInput",
512
+ ref: emailInput,
513
+ type: "text",
514
+ class: "atm-input-field",
515
+ placeholder: inputPlaceholder.value,
516
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => form.value.emailAddress = $event),
517
+ disabled: currentStep.value !== "email" || isLoading.value
518
+ }, null, 8, _hoisted_9$2), [
519
+ [vModelText, form.value.emailAddress]
520
+ ]),
521
+ fieldErrors.value.emailAddress.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_10$2, toDisplayString(fieldErrors.value.emailAddress[0]), 1)) : createCommentVNode("", true)
522
+ ])) : createCommentVNode("", true),
523
+ showPasswordField.value ? (openBlock(), createElementBlock("div", _hoisted_11$2, [
524
+ _cache[5] || (_cache[5] = createElementVNode("label", { class: "atm-input-label" }, "Senha", -1)),
525
+ withDirectives(createElementVNode("input", {
526
+ ref_key: "passwordInput",
527
+ ref: passwordInput,
528
+ type: "password",
529
+ class: "atm-input-field",
530
+ placeholder: "Digite sua senha",
531
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => form.value.password = $event),
532
+ disabled: isLoading.value
533
+ }, null, 8, _hoisted_12$2), [
534
+ [vModelText, form.value.password]
535
+ ]),
536
+ fieldErrors.value.password.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_13$2, toDisplayString(fieldErrors.value.password[0]), 1)) : createCommentVNode("", true),
537
+ createElementVNode("div", _hoisted_14$2, [
538
+ createElementVNode("button", {
539
+ type: "button",
540
+ onClick: _cache[2] || (_cache[2] = ($event) => sendResetPasswordLink()),
541
+ class: "atm-forgot-password-link",
542
+ disabled: isLoading.value
543
+ }, " Esqueci a minha senha ", 8, _hoisted_15$2)
544
+ ])
545
+ ])) : createCommentVNode("", true),
546
+ showStrategyChoice.value ? (openBlock(), createElementBlock("div", _hoisted_16$2, [
547
+ _cache[6] || (_cache[6] = createElementVNode("p", { class: "atm-strategy-title" }, "Escolha como deseja fazer login:", -1)),
548
+ createElementVNode("div", _hoisted_17$2, [
549
+ (openBlock(true), createElementBlock(Fragment, null, renderList(availableStrategies.value, (strategy) => {
550
+ return openBlock(), createElementBlock("button", {
551
+ key: strategy.strategy,
552
+ onClick: ($event) => selectStrategy(strategy),
553
+ type: "button",
554
+ class: "atm-strategy-button",
555
+ disabled: isLoading.value
556
+ }, [
557
+ strategy.strategy === "email_link" ? (openBlock(), createElementBlock("span", _hoisted_19$2, "Usar link por email")) : createCommentVNode("", true)
558
+ ], 8, _hoisted_18$2);
559
+ }), 128))
560
+ ])
561
+ ])) : createCommentVNode("", true),
562
+ currentStep.value === "email_link" ? (openBlock(), createElementBlock("div", _hoisted_20$2, [..._cache[7] || (_cache[7] = [
563
+ createElementVNode("p", { class: "atm-email-link-text" }, " Link de verificação enviado para seu email. Verifique sua caixa de entrada. ", -1)
564
+ ])])) : createCommentVNode("", true)
565
+ ])) : (openBlock(), createElementBlock("div", _hoisted_21$2, [
566
+ createElementVNode("p", null, [
567
+ _cache[8] || (_cache[8] = createTextVNode("Foi enviado um link para resetar a senha para o email ", -1)),
568
+ createElementVNode("strong", null, toDisplayString(form.value.emailAddress), 1),
569
+ _cache[9] || (_cache[9] = createTextVNode(". Verifique sua caixa de entrada.", -1))
570
+ ])
571
+ ])),
572
+ buttonText.value ? (openBlock(), createElementBlock("button", {
573
+ key: 2,
574
+ type: "submit",
575
+ class: "atm-login-button",
576
+ disabled: isLoading.value
577
+ }, [
578
+ !isLoading.value ? (openBlock(), createElementBlock("span", _hoisted_23$2, toDisplayString(buttonText.value), 1)) : (openBlock(), createElementBlock("span", _hoisted_24$2, [
579
+ _cache[10] || (_cache[10] = createElementVNode("svg", {
580
+ class: "spinner-svg",
581
+ viewBox: "0 0 50 50"
582
+ }, [
583
+ createElementVNode("circle", {
584
+ class: "spinner-circle",
585
+ cx: "25",
586
+ cy: "25",
587
+ r: "20",
588
+ fill: "none",
589
+ "stroke-width": "5"
590
+ })
591
+ ], -1)),
592
+ currentStep.value === "email" ? (openBlock(), createElementBlock("span", _hoisted_25$2, "Verificando...")) : (openBlock(), createElementBlock("span", _hoisted_26$2, "Entrando..."))
593
+ ]))
594
+ ], 8, _hoisted_22$2)) : createCommentVNode("", true),
595
+ createElementVNode("div", _hoisted_27$2, [
596
+ createElementVNode("p", _hoisted_28$1, [
597
+ _cache[11] || (_cache[11] = createTextVNode(" Ainda não tem uma conta? ", -1)),
598
+ createElementVNode("a", {
599
+ onClick: _cache[3] || (_cache[3] = ($event) => signUp()),
600
+ class: "atm-signup-link"
601
+ }, "Cadastre aqui")
602
+ ]),
603
+ _cache[12] || (_cache[12] = createElementVNode("p", { class: "atm-powered-by" }, [
604
+ createTextVNode(" Secured by "),
605
+ createElementVNode("strong", null, "Autenticar.me")
606
+ ], -1))
607
+ ])
608
+ ])
609
+ ], 32)) : createCommentVNode("", true);
610
+ };
611
+ }
612
+ });
613
+ const SignIn = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["__scopeId", "data-v-69af412a"]]);
614
+ const _hoisted_1$6 = {
615
+ key: 0,
616
+ class: "atm-notification-container"
617
+ };
618
+ const _sfc_main$a = /* @__PURE__ */ defineComponent({
619
+ __name: "Notification",
620
+ props: {
621
+ show: { type: Boolean },
622
+ message: {},
623
+ type: { default: "error" }
624
+ },
625
+ setup(__props) {
626
+ return (_ctx, _cache) => {
627
+ return openBlock(), createBlock(Teleport, { to: "body" }, [
628
+ createVNode(Transition, { name: "atm-notification" }, {
629
+ default: withCtx(() => [
630
+ __props.show ? (openBlock(), createElementBlock("div", _hoisted_1$6, [
631
+ createElementVNode("div", {
632
+ class: normalizeClass(["atm-notification", `atm-notification--${__props.type}`])
633
+ }, toDisplayString(__props.message), 3)
634
+ ])) : createCommentVNode("", true)
635
+ ]),
636
+ _: 1
637
+ })
638
+ ]);
639
+ };
640
+ }
641
+ });
642
+ const Notification = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["__scopeId", "data-v-f5e47084"]]);
643
+ const _hoisted_1$5 = { class: "atm-signup-container" };
644
+ const _hoisted_2$1 = { class: "atm-logo-container" };
645
+ const _hoisted_3$1 = ["src"];
646
+ const _hoisted_4$1 = {
647
+ key: 1,
648
+ class: "atm-logo-placeholder"
649
+ };
650
+ const _hoisted_5$1 = { class: "atm-project-name" };
651
+ const _hoisted_6$1 = {
652
+ key: 0,
653
+ class: "atm-form-group"
654
+ };
655
+ const _hoisted_7$1 = { class: "atm-input-label" };
656
+ const _hoisted_8$1 = ["disabled"];
657
+ const _hoisted_9$1 = {
658
+ key: 0,
659
+ class: "atm-field-error"
660
+ };
661
+ const _hoisted_10$1 = {
662
+ key: 1,
663
+ class: "atm-form-group"
664
+ };
665
+ const _hoisted_11$1 = { class: "atm-input-label" };
666
+ const _hoisted_12$1 = ["disabled"];
667
+ const _hoisted_13$1 = {
668
+ key: 0,
669
+ class: "atm-field-error"
670
+ };
671
+ const _hoisted_14$1 = { class: "atm-form-group" };
672
+ const _hoisted_15$1 = ["disabled"];
673
+ const _hoisted_16$1 = {
674
+ key: 0,
675
+ class: "atm-field-error"
676
+ };
677
+ const _hoisted_17$1 = {
678
+ key: 2,
679
+ class: "atm-form-group"
680
+ };
681
+ const _hoisted_18$1 = ["disabled"];
682
+ const _hoisted_19$1 = {
683
+ key: 0,
684
+ class: "atm-field-error"
685
+ };
686
+ const _hoisted_20$1 = {
687
+ key: 3,
688
+ class: "atm-form-group"
689
+ };
690
+ const _hoisted_21$1 = ["disabled"];
691
+ const _hoisted_22$1 = {
692
+ key: 0,
693
+ class: "atm-field-error"
694
+ };
695
+ const _hoisted_23$1 = ["disabled"];
696
+ const _hoisted_24$1 = { key: 0 };
697
+ const _hoisted_25$1 = {
698
+ key: 1,
699
+ class: "button-spinner"
700
+ };
701
+ const _hoisted_26$1 = { class: "atm-footer-links" };
702
+ const _hoisted_27$1 = { class: "atm-login-text" };
703
+ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
704
+ __name: "SignUp",
705
+ emits: ["completed", "sign-in"],
706
+ setup(__props, { emit: __emit }) {
707
+ useCssVars((_ctx) => ({
708
+ "v8c008960": atmPrimaryColor.value,
709
+ "v1183b75e": atmSecondaryColor.value
710
+ }));
711
+ const emit = __emit;
712
+ const { configurations } = useAtm();
713
+ const form = ref({
714
+ first_name: "",
715
+ last_name: "",
716
+ email_address: "",
717
+ password: "",
718
+ confirm_password: ""
719
+ });
720
+ const notification = ref({
721
+ show: false,
722
+ message: "",
723
+ type: "error"
724
+ });
725
+ const isLoading = ref(false);
726
+ const firstNameInput = ref(null);
727
+ const emailInput = ref(null);
728
+ const fieldErrors = ref({
729
+ first_name: [],
730
+ last_name: [],
731
+ email_address: [],
732
+ password: [],
733
+ confirm_password: []
734
+ });
735
+ const showNotification = (message, type = "error") => {
736
+ notification.value = {
737
+ show: true,
738
+ message,
739
+ type
740
+ };
741
+ setTimeout(() => {
742
+ notification.value.show = false;
743
+ }, 3e3);
744
+ };
745
+ onMounted(() => {
746
+ nextTick(() => {
747
+ if (hasFirstName.value && firstNameInput.value) {
748
+ firstNameInput.value.focus();
749
+ } else if (emailInput.value) {
750
+ emailInput.value.focus();
751
+ }
752
+ });
753
+ });
754
+ const atmPrimaryColor = computed(() => configurations.value?.design?.primaryColor);
755
+ const atmSecondaryColor = computed(() => configurations.value?.design?.secondaryColor);
756
+ const logoUrl = computed(() => configurations.value?.project?.logo || "");
757
+ const hasFirstName = computed(() => configurations.value?.firstName?.required === true);
758
+ const hasLastName = computed(() => configurations.value?.lastName?.required === true);
759
+ const hasPassword = computed(() => configurations.value?.password?.enable !== false);
760
+ const lengthConfig = computed(() => configurations.value?.password?.length);
761
+ const validatePassword = () => {
762
+ const password = form.value.password;
763
+ const minLength = lengthConfig.value?.min ?? 8;
764
+ const maxLength = lengthConfig.value?.max ?? 64;
765
+ if (password.length < minLength) {
766
+ return `Senha deve ter pelo menos ${minLength} caracteres`;
767
+ }
768
+ if (password.length > maxLength) {
769
+ return `Senha deve ter no máximo ${maxLength} caracteres`;
770
+ }
771
+ if (configurations.value?.password?.uppercase && !/[A-Z]/.test(password)) {
772
+ return "Senha deve conter pelo menos uma letra maiúscula";
773
+ }
774
+ if (configurations.value?.password?.lowercase && !/[a-z]/.test(password)) {
775
+ return "Senha deve conter pelo menos uma letra minúscula";
776
+ }
777
+ if (configurations.value?.password?.numbers && !/\d/.test(password)) {
778
+ return "Senha deve conter pelo menos um número";
779
+ }
780
+ if (configurations.value?.password?.symbols && !/[!@#$%^&*(),.?":{}|<>]/.test(password)) {
781
+ return "Senha deve conter pelo menos um símbolo especial";
782
+ }
783
+ return null;
784
+ };
785
+ const client = useAtmClient();
786
+ const { signInByAccessToken } = useAuth();
787
+ const clearErrors = () => {
788
+ fieldErrors.value = {
789
+ first_name: [],
790
+ last_name: [],
791
+ email_address: [],
792
+ password: [],
793
+ confirm_password: []
794
+ };
795
+ };
796
+ const submit = async () => {
797
+ if (isLoading.value) return;
798
+ clearErrors();
799
+ if (hasFirstName.value && !form.value.first_name.trim()) {
800
+ showNotification("Nome é obrigatório");
801
+ return;
802
+ }
803
+ if (hasLastName.value && !form.value.last_name.trim()) {
804
+ showNotification("Sobrenome é obrigatório");
805
+ return;
806
+ }
807
+ if (!form.value.email_address.trim()) {
808
+ showNotification("Email é obrigatório");
809
+ return;
810
+ }
811
+ if (hasPassword.value) {
812
+ if (!form.value.password.trim()) {
813
+ showNotification("Senha é obrigatória");
814
+ return;
815
+ }
816
+ const passwordError = validatePassword();
817
+ if (passwordError) {
818
+ showNotification(passwordError);
819
+ return;
820
+ }
821
+ if (!form.value.confirm_password.trim()) {
822
+ showNotification("Confirmação de senha é obrigatória");
823
+ return;
824
+ }
825
+ if (form.value.password !== form.value.confirm_password) {
826
+ showNotification("Senhas não coincidem");
827
+ return;
828
+ }
829
+ }
830
+ try {
831
+ isLoading.value = true;
832
+ await client.auth().register({
833
+ first_name: form.value.first_name,
834
+ last_name: form.value.last_name,
835
+ email_address: form.value.email_address,
836
+ password: form.value.password
837
+ });
838
+ showNotification("Conta criada com sucesso!", "success");
839
+ const deviceToken = await getDeviceToken(client);
840
+ const signInStep = await client.auth().signInByEmailAddress(form.value.email_address, deviceToken);
841
+ const attemptToken = signInStep.token;
842
+ if (!attemptToken) {
843
+ throw new Error("Token de tentativa não encontrado");
844
+ }
845
+ await client.auth().authenticateWithPassword(signInStep.id, attemptToken, form.value.password);
846
+ const tokens = await client.auth().generateTokens(signInStep.id, attemptToken);
847
+ signInByAccessToken(tokens.access_token);
848
+ writeRefreshTokenInCookie(tokens.refresh_token);
849
+ showNotification("Login realizado com sucesso!", "success");
850
+ setTimeout(() => {
851
+ emit("completed");
852
+ }, 1e3);
853
+ } catch (error) {
854
+ if (error.errors && typeof error.errors === "object") {
855
+ fieldErrors.value = { ...fieldErrors.value, ...error.errors };
856
+ } else {
857
+ showNotification(error.message || "Erro ao registrar usuário", "error");
858
+ }
859
+ isLoading.value = false;
860
+ }
861
+ };
862
+ const signIn = () => emit("sign-in");
863
+ return (_ctx, _cache) => {
864
+ return openBlock(), createElementBlock(Fragment, null, [
865
+ createVNode(Notification, {
866
+ show: notification.value.show,
867
+ message: notification.value.message,
868
+ type: notification.value.type
869
+ }, null, 8, ["show", "message", "type"]),
870
+ unref(configurations) ? (openBlock(), createElementBlock("form", {
871
+ key: 0,
872
+ onSubmit: withModifiers(submit, ["prevent"])
873
+ }, [
874
+ createElementVNode("div", _hoisted_1$5, [
875
+ createElementVNode("div", _hoisted_2$1, [
876
+ logoUrl.value ? (openBlock(), createElementBlock("img", {
877
+ key: 0,
878
+ src: logoUrl.value,
879
+ alt: "Logo",
880
+ class: "atm-logo-image"
881
+ }, null, 8, _hoisted_3$1)) : (openBlock(), createElementBlock("div", _hoisted_4$1, "Logo"))
882
+ ]),
883
+ createElementVNode("h2", _hoisted_5$1, toDisplayString(unref(configurations).project.name), 1),
884
+ _cache[11] || (_cache[11] = createElementVNode("p", { class: "atm-welcome-text" }, "Crie sua conta para começar", -1)),
885
+ hasFirstName.value ? (openBlock(), createElementBlock("div", _hoisted_6$1, [
886
+ createElementVNode("label", _hoisted_7$1, " Primeiro Nome " + toDisplayString(unref(configurations).firstName?.required ? "*" : ""), 1),
887
+ withDirectives(createElementVNode("input", {
888
+ ref_key: "firstNameInput",
889
+ ref: firstNameInput,
890
+ type: "text",
891
+ class: "atm-input-field",
892
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => form.value.first_name = $event),
893
+ placeholder: "Digite seu primeiro nome",
894
+ disabled: isLoading.value
895
+ }, null, 8, _hoisted_8$1), [
896
+ [vModelText, form.value.first_name]
897
+ ]),
898
+ fieldErrors.value.first_name.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_9$1, toDisplayString(fieldErrors.value.first_name[0]), 1)) : createCommentVNode("", true)
899
+ ])) : createCommentVNode("", true),
900
+ hasLastName.value ? (openBlock(), createElementBlock("div", _hoisted_10$1, [
901
+ createElementVNode("label", _hoisted_11$1, " Sobrenome " + toDisplayString(unref(configurations).lastName?.required ? "*" : ""), 1),
902
+ withDirectives(createElementVNode("input", {
903
+ type: "text",
904
+ class: "atm-input-field",
905
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => form.value.last_name = $event),
906
+ placeholder: "Digite seu sobrenome",
907
+ disabled: isLoading.value
908
+ }, null, 8, _hoisted_12$1), [
909
+ [vModelText, form.value.last_name]
910
+ ]),
911
+ fieldErrors.value.last_name.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_13$1, toDisplayString(fieldErrors.value.last_name[0]), 1)) : createCommentVNode("", true)
912
+ ])) : createCommentVNode("", true),
913
+ createElementVNode("div", _hoisted_14$1, [
914
+ _cache[5] || (_cache[5] = createElementVNode("label", { class: "atm-input-label" }, "Email ou Nome de usuário *", -1)),
915
+ withDirectives(createElementVNode("input", {
916
+ ref_key: "emailInput",
917
+ ref: emailInput,
918
+ type: "text",
919
+ class: "atm-input-field",
920
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => form.value.email_address = $event),
921
+ placeholder: "email@exemplo.com ou seuusername",
922
+ disabled: isLoading.value
923
+ }, null, 8, _hoisted_15$1), [
924
+ [vModelText, form.value.email_address]
925
+ ]),
926
+ fieldErrors.value.email_address.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_16$1, toDisplayString(fieldErrors.value.email_address[0]), 1)) : createCommentVNode("", true)
927
+ ]),
928
+ hasPassword.value ? (openBlock(), createElementBlock("div", _hoisted_17$1, [
929
+ _cache[6] || (_cache[6] = createElementVNode("label", { class: "atm-input-label" }, "Senha *", -1)),
930
+ withDirectives(createElementVNode("input", {
931
+ type: "password",
932
+ class: "atm-input-field",
933
+ "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => form.value.password = $event),
934
+ placeholder: "",
935
+ disabled: isLoading.value
936
+ }, null, 8, _hoisted_18$1), [
937
+ [vModelText, form.value.password]
938
+ ]),
939
+ fieldErrors.value.password.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_19$1, toDisplayString(fieldErrors.value.password[0]), 1)) : createCommentVNode("", true)
940
+ ])) : createCommentVNode("", true),
941
+ hasPassword.value ? (openBlock(), createElementBlock("div", _hoisted_20$1, [
942
+ _cache[7] || (_cache[7] = createElementVNode("label", { class: "atm-input-label" }, "Confirmar Senha *", -1)),
943
+ withDirectives(createElementVNode("input", {
944
+ type: "password",
945
+ class: "atm-input-field",
946
+ "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => form.value.confirm_password = $event),
947
+ placeholder: "",
948
+ disabled: isLoading.value
949
+ }, null, 8, _hoisted_21$1), [
950
+ [vModelText, form.value.confirm_password]
951
+ ]),
952
+ fieldErrors.value.confirm_password.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_22$1, toDisplayString(fieldErrors.value.confirm_password[0]), 1)) : createCommentVNode("", true)
953
+ ])) : createCommentVNode("", true),
954
+ createElementVNode("button", {
955
+ type: "submit",
956
+ class: "atm-signup-button",
957
+ disabled: isLoading.value
958
+ }, [
959
+ !isLoading.value ? (openBlock(), createElementBlock("span", _hoisted_24$1, "Criar Conta")) : (openBlock(), createElementBlock("span", _hoisted_25$1, [..._cache[8] || (_cache[8] = [
960
+ createElementVNode("svg", {
961
+ class: "spinner-svg",
962
+ viewBox: "0 0 50 50"
963
+ }, [
964
+ createElementVNode("circle", {
965
+ class: "spinner-circle",
966
+ cx: "25",
967
+ cy: "25",
968
+ r: "20",
969
+ fill: "none",
970
+ "stroke-width": "5"
971
+ })
972
+ ], -1),
973
+ createTextVNode(" Criando... ", -1)
974
+ ])]))
975
+ ], 8, _hoisted_23$1),
976
+ createElementVNode("div", _hoisted_26$1, [
977
+ createElementVNode("p", _hoisted_27$1, [
978
+ _cache[9] || (_cache[9] = createTextVNode(" Já tem uma conta? ", -1)),
979
+ createElementVNode("a", {
980
+ onClick: signIn,
981
+ class: normalizeClass(["atm-login-link", { "disabled-link": isLoading.value }])
982
+ }, "Faça login", 2)
983
+ ]),
984
+ _cache[10] || (_cache[10] = createElementVNode("p", { class: "atm-powered-by" }, [
985
+ createTextVNode("Secured by "),
986
+ createElementVNode("strong", null, "Autenticar.me")
987
+ ], -1))
988
+ ])
989
+ ])
990
+ ], 32)) : createCommentVNode("", true)
991
+ ], 64);
992
+ };
993
+ }
994
+ });
995
+ const SignUp = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["__scopeId", "data-v-de716df2"]]);
996
+ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
997
+ __name: "SignInModal",
998
+ emits: [
999
+ "close"
1000
+ ],
1001
+ setup(__props, { emit: __emit }) {
1002
+ const emit = __emit;
1003
+ const close = () => {
1004
+ emit("close");
1005
+ };
1006
+ const component = ref("sign-in");
1007
+ const signUp = () => component.value = "sign-up";
1008
+ const signIn = () => component.value = "sign-in";
1009
+ const windowWidth = ref(typeof window !== "undefined" ? window.innerWidth : 1024);
1010
+ const maxWidth = computed(() => {
1011
+ if (windowWidth.value <= 360) return 340;
1012
+ if (windowWidth.value <= 480) return windowWidth.value - 20;
1013
+ if (windowWidth.value <= 768) return 400;
1014
+ return 420;
1015
+ });
1016
+ const updateWidth = () => {
1017
+ windowWidth.value = window.innerWidth;
1018
+ };
1019
+ onMounted(() => {
1020
+ window.addEventListener("resize", updateWidth);
1021
+ });
1022
+ onUnmounted(() => {
1023
+ window.removeEventListener("resize", updateWidth);
1024
+ });
1025
+ return (_ctx, _cache) => {
1026
+ return openBlock(), createBlock(Modal, {
1027
+ "max-width": maxWidth.value,
1028
+ onClose: _cache[4] || (_cache[4] = ($event) => close())
1029
+ }, {
1030
+ default: withCtx(() => [
1031
+ component.value === "sign-in" ? (openBlock(), createBlock(SignIn, {
1032
+ key: 0,
1033
+ onSignUp: _cache[0] || (_cache[0] = ($event) => signUp()),
1034
+ onCompleted: _cache[1] || (_cache[1] = ($event) => close())
1035
+ })) : createCommentVNode("", true),
1036
+ component.value === "sign-up" ? (openBlock(), createBlock(SignUp, {
1037
+ key: 1,
1038
+ onSignIn: _cache[2] || (_cache[2] = ($event) => signIn()),
1039
+ onCompleted: _cache[3] || (_cache[3] = ($event) => close())
1040
+ })) : createCommentVNode("", true)
1041
+ ]),
1042
+ _: 1
1043
+ }, 8, ["max-width"]);
1044
+ };
1045
+ }
1046
+ });
1047
+ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
1048
+ __name: "SignInButton",
1049
+ setup(__props) {
1050
+ useCssVars((_ctx) => ({
1051
+ "v0f0ded3a": atmPrimaryColor.value
1052
+ }));
1053
+ const showSignInModal = ref(false);
1054
+ const { configurations } = useAtm();
1055
+ const atmPrimaryColor = computed(() => configurations.value?.design?.primaryColor);
1056
+ const notification = ref({
1057
+ show: false,
1058
+ message: "",
1059
+ type: "error"
1060
+ });
1061
+ const showNotification = (message, type = "error") => {
1062
+ notification.value = {
1063
+ show: true,
1064
+ message,
1065
+ type
1066
+ };
1067
+ setTimeout(() => {
1068
+ notification.value.show = false;
1069
+ }, 3e3);
1070
+ };
1071
+ provide("showNotification", showNotification);
1072
+ const signIn = () => {
1073
+ showSignInModal.value = true;
1074
+ };
1075
+ return (_ctx, _cache) => {
1076
+ return openBlock(), createElementBlock(Fragment, null, [
1077
+ createVNode(Notification, {
1078
+ show: notification.value.show,
1079
+ message: notification.value.message,
1080
+ type: notification.value.type
1081
+ }, null, 8, ["show", "message", "type"]),
1082
+ showSignInModal.value ? (openBlock(), createBlock(_sfc_main$8, {
1083
+ key: 0,
1084
+ onClose: _cache[0] || (_cache[0] = () => showSignInModal.value = false)
1085
+ })) : createCommentVNode("", true),
1086
+ createElementVNode("button", {
1087
+ onClick: _cache[1] || (_cache[1] = ($event) => signIn()),
1088
+ class: "atm-signin-btn"
1089
+ }, " Entrar ")
1090
+ ], 64);
1091
+ };
1092
+ }
1093
+ });
1094
+ const SignInButton = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["__scopeId", "data-v-4139c6d0"]]);
1095
+ const _hoisted_1$4 = {
1096
+ key: 2,
1097
+ style: { "padding": "24px", "text-align": "center" }
1098
+ };
1099
+ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
1100
+ __name: "SignUpModal",
1101
+ emits: [
1102
+ "close"
1103
+ ],
1104
+ setup(__props, { emit: __emit }) {
1105
+ const { configurations } = useAtm();
1106
+ const emit = __emit;
1107
+ const close = () => {
1108
+ emit("close");
1109
+ };
1110
+ const component = ref("sign-up");
1111
+ const isRegistrationAllowed = computed(() => configurations.value?.register?.enable !== false);
1112
+ const signUp = () => component.value = "sign-up";
1113
+ const signIn = () => component.value = "sign-in";
1114
+ const windowWidth = ref(typeof window !== "undefined" ? window.innerWidth : 1024);
1115
+ const maxWidth = computed(() => {
1116
+ if (windowWidth.value <= 360) return 340;
1117
+ if (windowWidth.value <= 480) return windowWidth.value - 20;
1118
+ if (windowWidth.value <= 768) return 400;
1119
+ return 420;
1120
+ });
1121
+ const updateWidth = () => {
1122
+ windowWidth.value = window.innerWidth;
1123
+ };
1124
+ onMounted(() => {
1125
+ window.addEventListener("resize", updateWidth);
1126
+ });
1127
+ onUnmounted(() => {
1128
+ window.removeEventListener("resize", updateWidth);
1129
+ });
1130
+ return (_ctx, _cache) => {
1131
+ return openBlock(), createBlock(Modal, {
1132
+ "max-width": maxWidth.value,
1133
+ onClose: _cache[5] || (_cache[5] = ($event) => close())
1134
+ }, {
1135
+ default: withCtx(() => [
1136
+ component.value === "sign-in" ? (openBlock(), createBlock(SignIn, {
1137
+ key: 0,
1138
+ onSignUp: _cache[0] || (_cache[0] = ($event) => signUp()),
1139
+ onCompleted: _cache[1] || (_cache[1] = ($event) => close())
1140
+ })) : createCommentVNode("", true),
1141
+ component.value === "sign-up" && isRegistrationAllowed.value ? (openBlock(), createBlock(SignUp, {
1142
+ key: 1,
1143
+ onSignIn: _cache[2] || (_cache[2] = ($event) => signIn()),
1144
+ onCompleted: _cache[3] || (_cache[3] = ($event) => close())
1145
+ })) : component.value === "sign-up" ? (openBlock(), createElementBlock("div", _hoisted_1$4, [
1146
+ _cache[6] || (_cache[6] = createElementVNode("p", { style: { "margin-bottom": "16px" } }, "Registro não está disponível no momento", -1)),
1147
+ createElementVNode("button", {
1148
+ onClick: _cache[4] || (_cache[4] = ($event) => signIn()),
1149
+ style: { "padding": "12px 24px", "background": "#007bff", "color": "white", "border": "none", "border-radius": "6px", "cursor": "pointer" }
1150
+ }, "Fazer login")
1151
+ ])) : createCommentVNode("", true)
1152
+ ]),
1153
+ _: 1
1154
+ }, 8, ["max-width"]);
1155
+ };
1156
+ }
1157
+ });
1158
+ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
1159
+ __name: "SignUpButton",
1160
+ setup(__props) {
1161
+ useCssVars((_ctx) => ({
1162
+ "v1112fbaa": atmPrimaryColor.value
1163
+ }));
1164
+ const showSignUpModal = ref(false);
1165
+ const { configurations } = useAtm();
1166
+ const atmPrimaryColor = computed(() => configurations.value?.design?.primaryColor);
1167
+ const isRegistrationAllowed = computed(() => configurations.value?.register?.enable !== false);
1168
+ const signUp = () => {
1169
+ showSignUpModal.value = true;
1170
+ };
1171
+ return (_ctx, _cache) => {
1172
+ return openBlock(), createElementBlock(Fragment, null, [
1173
+ showSignUpModal.value ? (openBlock(), createBlock(_sfc_main$6, {
1174
+ key: 0,
1175
+ onClose: _cache[0] || (_cache[0] = () => showSignUpModal.value = false)
1176
+ })) : createCommentVNode("", true),
1177
+ isRegistrationAllowed.value ? (openBlock(), createElementBlock("button", {
1178
+ key: 1,
1179
+ onClick: _cache[1] || (_cache[1] = ($event) => signUp()),
1180
+ class: "atm-signup-btn"
1181
+ }, " Cadastrar-se ")) : createCommentVNode("", true)
1182
+ ], 64);
1183
+ };
1184
+ }
1185
+ });
1186
+ const SignUpButton = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-959aa7ef"]]);
1187
+ const _hoisted_1$3 = {
1188
+ key: 0,
1189
+ class: "atm-profile-container"
1190
+ };
1191
+ const _hoisted_2 = ["src"];
1192
+ const _hoisted_3 = { key: 1 };
1193
+ const _hoisted_4 = {
1194
+ key: 2,
1195
+ viewBox: "0 0 24 24",
1196
+ class: "atm-btn-icon",
1197
+ style: { "width": "20px", "height": "20px", "color": "white" }
1198
+ };
1199
+ const _hoisted_5 = {
1200
+ key: 0,
1201
+ class: "atm-profile-name"
1202
+ };
1203
+ const _hoisted_6 = {
1204
+ key: 0,
1205
+ class: "atm-profile-menu"
1206
+ };
1207
+ const _hoisted_7 = { class: "atm-profile-info" };
1208
+ const _hoisted_8 = ["src"];
1209
+ const _hoisted_9 = { key: 1 };
1210
+ const _hoisted_10 = {
1211
+ key: 2,
1212
+ viewBox: "0 0 24 24",
1213
+ class: "atm-btn-icon",
1214
+ style: { "width": "40px", "height": "40px", "color": "white" }
1215
+ };
1216
+ const _hoisted_11 = { class: "atm-profile-details" };
1217
+ const _hoisted_12 = {
1218
+ key: 0,
1219
+ class: "atm-profile-fullname"
1220
+ };
1221
+ const _hoisted_13 = {
1222
+ key: 1,
1223
+ class: "atm-profile-fullname"
1224
+ };
1225
+ const _hoisted_14 = { class: "atm-profile-email" };
1226
+ const _hoisted_15 = {
1227
+ key: 0,
1228
+ class: "atm-profile-modal",
1229
+ role: "dialog",
1230
+ "aria-modal": "true",
1231
+ "aria-labelledby": "profile-modal-title"
1232
+ };
1233
+ const _hoisted_16 = { class: "atm-profile-content" };
1234
+ const _hoisted_17 = { class: "atm-profile-tabs" };
1235
+ const _hoisted_18 = {
1236
+ key: 0,
1237
+ class: "atm-profile-body"
1238
+ };
1239
+ const _hoisted_19 = ["src"];
1240
+ const _hoisted_20 = { key: 1 };
1241
+ const _hoisted_21 = {
1242
+ key: 2,
1243
+ viewBox: "0 0 24 24",
1244
+ class: "atm-btn-icon",
1245
+ style: { "width": "80px", "height": "80px", "color": "white", "margin": "0 auto" }
1246
+ };
1247
+ const _hoisted_22 = {
1248
+ key: 0,
1249
+ class: "atm-profile-info-grid"
1250
+ };
1251
+ const _hoisted_23 = { class: "atm-profile-info-row" };
1252
+ const _hoisted_24 = {
1253
+ key: 0,
1254
+ class: "atm-profile-info-value"
1255
+ };
1256
+ const _hoisted_25 = {
1257
+ key: 1,
1258
+ class: "atm-profile-info-value"
1259
+ };
1260
+ const _hoisted_26 = { class: "atm-profile-info-row" };
1261
+ const _hoisted_27 = {
1262
+ key: 0,
1263
+ class: "atm-profile-info-value"
1264
+ };
1265
+ const _hoisted_28 = {
1266
+ key: 1,
1267
+ class: "atm-profile-info-value"
1268
+ };
1269
+ const _hoisted_29 = { class: "atm-profile-info-row" };
1270
+ const _hoisted_30 = { class: "atm-profile-info-value" };
1271
+ const _hoisted_31 = {
1272
+ key: 1,
1273
+ class: "atm-profile-edit-form"
1274
+ };
1275
+ const _hoisted_32 = { class: "atm-form-group" };
1276
+ const _hoisted_33 = { class: "atm-form-group" };
1277
+ const _hoisted_34 = {
1278
+ key: 1,
1279
+ class: "atm-profile-body"
1280
+ };
1281
+ const _hoisted_35 = { class: "atm-email-add-section" };
1282
+ const _hoisted_36 = { class: "atm-form-group" };
1283
+ const _hoisted_37 = { class: "atm-badge" };
1284
+ const _hoisted_38 = { class: "atm-email-list" };
1285
+ const _hoisted_39 = { class: "atm-email-info" };
1286
+ const _hoisted_40 = { class: "atm-email-address" };
1287
+ const _hoisted_41 = { class: "atm-email-badges" };
1288
+ const _hoisted_42 = {
1289
+ key: 0,
1290
+ class: "atm-badge atm-badge-primary"
1291
+ };
1292
+ const _hoisted_43 = {
1293
+ key: 1,
1294
+ class: "atm-badge atm-badge-verified"
1295
+ };
1296
+ const _hoisted_44 = {
1297
+ key: 2,
1298
+ class: "atm-badge atm-badge-unverified"
1299
+ };
1300
+ const _hoisted_45 = { class: "atm-email-actions" };
1301
+ const _hoisted_46 = ["onClick"];
1302
+ const _hoisted_47 = ["onClick"];
1303
+ const _hoisted_48 = {
1304
+ key: 2,
1305
+ class: "atm-profile-body"
1306
+ };
1307
+ const _hoisted_49 = {
1308
+ key: 3,
1309
+ class: "atm-profile-body"
1310
+ };
1311
+ const _hoisted_50 = { class: "atm-sessions-section" };
1312
+ const _hoisted_51 = { class: "atm-sessions-list" };
1313
+ const _hoisted_52 = { class: "atm-session-info" };
1314
+ const _hoisted_53 = { class: "atm-session-header" };
1315
+ const _hoisted_54 = {
1316
+ viewBox: "0 0 24 24",
1317
+ class: "atm-session-icon"
1318
+ };
1319
+ const _hoisted_55 = ["d"];
1320
+ const _hoisted_56 = { class: "atm-session-details" };
1321
+ const _hoisted_57 = { class: "atm-session-title" };
1322
+ const _hoisted_58 = {
1323
+ key: 0,
1324
+ class: "atm-badge atm-badge-current"
1325
+ };
1326
+ const _hoisted_59 = {
1327
+ key: 0,
1328
+ class: "atm-session-device-info"
1329
+ };
1330
+ const _hoisted_60 = { key: 0 };
1331
+ const _hoisted_61 = { key: 1 };
1332
+ const _hoisted_62 = { key: 2 };
1333
+ const _hoisted_63 = { class: "atm-session-timestamps" };
1334
+ const _hoisted_64 = { class: "atm-session-timestamp" };
1335
+ const _hoisted_65 = { class: "atm-session-timestamp" };
1336
+ const _hoisted_66 = { class: "atm-session-actions" };
1337
+ const _hoisted_67 = ["onClick"];
1338
+ const _sfc_main$4 = /* @__PURE__ */ defineComponent({
1339
+ __name: "UserProfile",
1340
+ setup(__props) {
1341
+ useCssVars((_ctx) => ({
1342
+ "v1982ae74": atmPrimaryColor.value,
1343
+ "c7d31cfc": atmSecondaryColor.value
1344
+ }));
1345
+ const { user, logout } = useAuth();
1346
+ const { configurations } = useAtm();
1347
+ const atmPrimaryColor = computed(() => configurations.value?.design?.primaryColor);
1348
+ const atmSecondaryColor = computed(() => configurations.value?.design?.secondaryColor);
1349
+ const isDropdownOpen = ref(false);
1350
+ const isProfileModalOpen = ref(false);
1351
+ const isEditingProfile = ref(false);
1352
+ const buttonRef = ref(null);
1353
+ const emailAddresses = ref([]);
1354
+ const newEmail = ref("");
1355
+ const activeTab = ref("geral");
1356
+ const sessions = ref([]);
1357
+ const client = useAtmClient();
1358
+ const profileForm = ref({
1359
+ firstName: "",
1360
+ lastName: "",
1361
+ primaryEmailAddress: ""
1362
+ });
1363
+ const notification = ref({
1364
+ show: false,
1365
+ message: "",
1366
+ type: "error"
1367
+ });
1368
+ const showNotification = (message, type = "error") => {
1369
+ notification.value = {
1370
+ show: true,
1371
+ message,
1372
+ type
1373
+ };
1374
+ setTimeout(() => {
1375
+ notification.value.show = false;
1376
+ }, 3e3);
1377
+ };
1378
+ provide("showNotification", showNotification);
1379
+ const userInitials = computed(() => {
1380
+ if (!user.value || !user.value.firstName) return "";
1381
+ return (user.value.firstName.charAt(0) + (user.value.lastName?.charAt(0) || "")).toUpperCase();
1382
+ });
1383
+ const toggleMenu = () => isDropdownOpen.value = !isDropdownOpen.value;
1384
+ const closeMenu = (event) => {
1385
+ if (buttonRef.value && !buttonRef.value.contains(event.target)) {
1386
+ isDropdownOpen.value = false;
1387
+ }
1388
+ };
1389
+ const openProfileModal = async () => {
1390
+ isDropdownOpen.value = false;
1391
+ isProfileModalOpen.value = true;
1392
+ activeTab.value = "geral";
1393
+ resetProfileForm();
1394
+ await loadEmailAddresses();
1395
+ await loadSessions();
1396
+ };
1397
+ const closeProfileModal = () => {
1398
+ isProfileModalOpen.value = false;
1399
+ isEditingProfile.value = false;
1400
+ resetProfileForm();
1401
+ emailAddresses.value = [];
1402
+ newEmail.value = "";
1403
+ sessions.value = [];
1404
+ activeTab.value = "geral";
1405
+ };
1406
+ const resetProfileForm = () => {
1407
+ if (user.value) {
1408
+ profileForm.value = {
1409
+ firstName: user.value.firstName || "",
1410
+ lastName: user.value.lastName || "",
1411
+ primaryEmailAddress: user.value.primaryEmailAddress || ""
1412
+ };
1413
+ }
1414
+ };
1415
+ const updateProfileFormWithData = (profileDataUpdated) => {
1416
+ if (profileDataUpdated.first_name) {
1417
+ profileForm.value.firstName = profileDataUpdated.first_name;
1418
+ }
1419
+ if (profileDataUpdated.last_name) {
1420
+ profileForm.value.lastName = profileDataUpdated.last_name;
1421
+ }
1422
+ if (profileDataUpdated.primary_email_address) {
1423
+ profileForm.value.primaryEmailAddress = profileDataUpdated.primary_email_address;
1424
+ }
1425
+ };
1426
+ const loadEmailAddresses = async () => {
1427
+ try {
1428
+ const token = getCookie("atm_access_token");
1429
+ if (!token) {
1430
+ showNotification("Token de acesso não encontrado", "error");
1431
+ return;
1432
+ }
1433
+ const emails = await client.account(token).getEmailsAddresses();
1434
+ emailAddresses.value = emails;
1435
+ } catch (error) {
1436
+ showNotification("Erro ao carregar endereços de email", "error");
1437
+ }
1438
+ };
1439
+ const requestEmailVerification = async (emailId) => {
1440
+ try {
1441
+ const token = getCookie("atm_access_token");
1442
+ if (!token) {
1443
+ showNotification("Token de acesso não encontrado", "error");
1444
+ return;
1445
+ }
1446
+ await client.account(token).requestEmailVerification(emailId);
1447
+ showNotification("Link de verificação enviado para o email", "success");
1448
+ await loadEmailAddresses();
1449
+ } catch (error) {
1450
+ showNotification("Erro ao enviar verificação de email", "error");
1451
+ }
1452
+ };
1453
+ const deleteEmailAddress = async (emailId) => {
1454
+ try {
1455
+ const token = getCookie("atm_access_token");
1456
+ if (!token) {
1457
+ showNotification("Token de acesso não encontrado", "error");
1458
+ return;
1459
+ }
1460
+ await client.account(token).deleteEmailAddress(emailId);
1461
+ showNotification("Email removido com sucesso", "success");
1462
+ await loadEmailAddresses();
1463
+ } catch (error) {
1464
+ showNotification("Erro ao remover email", "error");
1465
+ }
1466
+ };
1467
+ const createEmailAddress = async () => {
1468
+ try {
1469
+ const token = getCookie("atm_access_token");
1470
+ if (!token) {
1471
+ showNotification("Token de acesso não encontrado", "error");
1472
+ return;
1473
+ }
1474
+ if (!newEmail.value.trim()) {
1475
+ showNotification("Informe o novo email", "error");
1476
+ return;
1477
+ }
1478
+ await client.account(token).createEmailAddress(newEmail.value.trim());
1479
+ showNotification("Email adicionado. Verifique sua caixa de entrada.", "success");
1480
+ newEmail.value = "";
1481
+ await loadEmailAddresses();
1482
+ } catch (error) {
1483
+ showNotification("Erro ao adicionar email", "error");
1484
+ }
1485
+ };
1486
+ const startEditing = () => {
1487
+ isEditingProfile.value = true;
1488
+ };
1489
+ const cancelEditing = () => {
1490
+ isEditingProfile.value = false;
1491
+ resetProfileForm();
1492
+ };
1493
+ const getCookie = (name) => {
1494
+ const value = `; ${document.cookie}`;
1495
+ const parts = value.split(`; ${name}=`);
1496
+ if (parts.length === 2) return parts.pop()?.split(";").shift() || null;
1497
+ return null;
1498
+ };
1499
+ const updateProfile = async () => {
1500
+ try {
1501
+ if (!profileForm.value.firstName.trim()) {
1502
+ showNotification("Nome é obrigatório", "error");
1503
+ return;
1504
+ }
1505
+ if (!profileForm.value.lastName.trim()) {
1506
+ showNotification("Sobrenome é obrigatório", "error");
1507
+ return;
1508
+ }
1509
+ const updateData = {};
1510
+ if (profileForm.value.firstName !== user.value?.firstName) {
1511
+ updateData.first_name = profileForm.value.firstName.trim();
1512
+ }
1513
+ if (profileForm.value.lastName !== user.value?.lastName) {
1514
+ updateData.last_name = profileForm.value.lastName.trim();
1515
+ }
1516
+ if (Object.keys(updateData).length === 0) {
1517
+ showNotification("Nenhuma alteração foi feita", "warning");
1518
+ isEditingProfile.value = false;
1519
+ return;
1520
+ }
1521
+ const token = getCookie("atm_access_token");
1522
+ if (!token) {
1523
+ showNotification("Token de acesso não encontrado", "error");
1524
+ return;
1525
+ }
1526
+ await client.account(token).updateProfile(updateData);
1527
+ const profileDataUpdated = await client.account(token).getProfile();
1528
+ updateProfileFormWithData(profileDataUpdated);
1529
+ showNotification("Perfil atualizado com sucesso!", "success");
1530
+ isEditingProfile.value = false;
1531
+ } catch (error) {
1532
+ showNotification(error.message || "Erro ao atualizar perfil", "error");
1533
+ }
1534
+ };
1535
+ const logoutUser = () => {
1536
+ logout();
1537
+ isDropdownOpen.value = false;
1538
+ };
1539
+ const sendResetPasswordLink = async () => {
1540
+ if (!user.value?.primaryEmailAddress) {
1541
+ showNotification("Informe o email para enviar o link de recuperação", "error");
1542
+ return;
1543
+ }
1544
+ try {
1545
+ await client.auth().resetPassword({ email_address: user.value.primaryEmailAddress });
1546
+ showNotification(`Foi enviado um link para resetar a senha para o email ${user.value.primaryEmailAddress}.`, "success");
1547
+ } catch (e) {
1548
+ showNotification(e.message || "Erro ao solicitar recuperação de senha", "error");
1549
+ }
1550
+ };
1551
+ const loadSessions = async () => {
1552
+ try {
1553
+ const token = getCookie("atm_access_token");
1554
+ if (!token) {
1555
+ showNotification("Token de acesso não encontrado", "error");
1556
+ return;
1557
+ }
1558
+ const sessionsData = await client.account(token).getSessions();
1559
+ sessions.value = sessionsData;
1560
+ } catch (error) {
1561
+ showNotification("Erro ao carregar sessões", "error");
1562
+ }
1563
+ };
1564
+ const closeSessionById = async (sessionId) => {
1565
+ try {
1566
+ const token = getCookie("atm_access_token");
1567
+ if (!token) {
1568
+ showNotification("Token de acesso não encontrado", "error");
1569
+ return;
1570
+ }
1571
+ await client.account(token).closeSession(sessionId);
1572
+ showNotification("Sessão encerrada com sucesso", "success");
1573
+ await loadSessions();
1574
+ } catch (error) {
1575
+ showNotification("Erro ao encerrar sessão", "error");
1576
+ }
1577
+ };
1578
+ const formatDate = (dateString) => {
1579
+ const date = new Date(dateString);
1580
+ return date.toLocaleString("pt-BR", {
1581
+ day: "2-digit",
1582
+ month: "2-digit",
1583
+ year: "numeric",
1584
+ hour: "2-digit",
1585
+ minute: "2-digit"
1586
+ });
1587
+ };
1588
+ const getDeviceIcon = (device) => {
1589
+ const platform = device.platform?.toLowerCase() || "";
1590
+ const browser = device.browser?.toLowerCase() || "";
1591
+ if (platform.includes("windows") || platform.includes("win32") || platform.includes("win64")) {
1592
+ return "M0,0V11H11V0ZM13,0V11H24V0ZM0,13V24H11V13ZM13,13V24H24V13Z";
1593
+ }
1594
+ if (platform.includes("mac") || platform.includes("darwin") || platform.includes("os x")) {
1595
+ return "M12,1C7,1 3,5 3,10C3,14 6,17 9,18V22H15V18C18,17 21,14 21,10C21,5 17,1 12,1M12,3C15.9,3 19,6.1 19,10C19,13.4 16.6,16.2 13.4,16.8L13,16.9V20H11V16.9L10.6,16.8C7.4,16.2 5,13.4 5,10C5,6.1 8.1,3 12,3Z";
1596
+ }
1597
+ if (platform.includes("iphone") || platform.includes("ipad") || platform.includes("ipod") || platform.includes("ios")) {
1598
+ return "M15.5,1H8.5C7.67,1 7,1.67 7,2.5V21.5C7,22.33 7.67,23 8.5,23H15.5C16.33,23 17,22.33 17,21.5V2.5C17,1.67 16.33,1 15.5,1M12,22C11.45,22 11,21.55 11,21C11,20.45 11.45,20 12,20C12.55,20 13,20.45 13,21C13,21.55 12.55,22 12,22M15,19H9V4H15V19Z";
1599
+ }
1600
+ if (platform.includes("android")) {
1601
+ return "M16.61,15.15C16.15,15.15 15.77,15.53 15.77,16C15.77,16.46 16.15,16.85 16.61,16.85C17.07,16.85 17.46,16.46 17.46,16C17.46,15.53 17.07,15.15 16.61,15.15M7.41,15.15C6.95,15.15 6.57,15.53 6.57,16C6.57,16.46 6.95,16.85 7.41,16.85C7.87,16.85 8.26,16.46 8.26,16C8.26,15.53 7.87,15.15 7.41,15.15M16.91,10.14L18.58,7.26C18.67,7.09 18.61,6.88 18.45,6.79C18.28,6.69 18.07,6.75 18,6.92L16.29,9.83C14.95,9.22 13.5,8.9 12,8.91C10.47,8.91 9,9.24 7.73,9.82L6.04,6.91C5.95,6.74 5.74,6.68 5.57,6.78C5.4,6.87 5.35,7.08 5.44,7.25L7.1,10.13C4.25,11.69 2.29,14.58 2,18H22C21.72,14.59 19.77,11.7 16.91,10.14Z";
1602
+ }
1603
+ if (platform.includes("linux") || platform.includes("ubuntu") || platform.includes("debian") || platform.includes("fedora") || platform.includes("centos") || platform.includes("arch")) {
1604
+ return "M12,2C11.5,2 11,2.19 10.59,2.59L2.59,10.59C1.8,11.37 1.8,12.63 2.59,13.41L10.59,21.41C11.37,22.2 12.63,22.2 13.41,21.41L21.41,13.41C22.2,12.63 22.2,11.37 21.41,10.59L13.41,2.59C13,2.19 12.5,2 12,2M12,4L20,12L12,20L4,12M12.5,7V13H11V7M12.5,15V17H11V15";
1605
+ }
1606
+ if (platform.includes("chrome") || browser.includes("chrome")) {
1607
+ return "M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,4C14.6,4 16.94,5.27 18.35,7.25L15.5,12C15.29,11.41 15,10.87 14.62,10.41C13.69,9.31 12.36,8.63 10.88,8.63C10.75,8.63 10.62,8.64 10.5,8.65L12,4.03C12,4.03 12,4 12,4M4.26,8.09C5.61,6.19 7.82,5 10.29,5L8.5,9.5C7.12,10.5 6.25,12.18 6.25,14.06C6.25,14.66 6.35,15.23 6.53,15.78L4.26,8.09M19.74,8.09L17.47,15.78C18.5,14.16 19.13,12.19 19.13,10.06C19.13,9.38 19.04,8.72 18.88,8.09H19.74M6.06,17C4.5,15.5 3.5,13.38 3.5,11C3.5,10.66 3.53,10.33 3.57,10H7.03C7,10.33 7,10.66 7,11C7,12.96 7.81,14.73 9.11,16L6.06,17M12,20C9.4,20 7.06,18.73 5.65,16.75L8.5,12C8.71,12.59 9,13.13 9.38,13.59C10.31,14.69 11.64,15.37 13.12,15.37C13.25,15.37 13.38,15.36 13.5,15.35L12,19.97C12,19.97 12,20 12,20M17.94,17L15.96,11C17.21,9.89 18,8.21 18,6.31C18,5.71 17.9,5.14 17.72,4.59L19.74,8.09C20.26,9.25 20.55,10.56 20.55,11.94C20.55,14.27 19.64,16.38 18.18,17.91L17.94,17Z";
1608
+ }
1609
+ if (browser.includes("firefox") || browser.includes("mozilla")) {
1610
+ return "M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M15.84,15.5C15.57,16.17 15.16,16.75 14.63,17.23C13.96,17.82 13.17,18.21 12.29,18.42C11.38,18.63 10.47,18.63 9.56,18.42C9,18.29 8.5,18.06 8.04,17.75C7.27,17.23 6.69,16.5 6.32,15.63C5.95,14.76 5.79,13.81 5.86,12.86C5.93,11.91 6.24,11.03 6.77,10.24C7.3,9.45 8,8.84 8.84,8.45C9.68,8.06 10.58,7.93 11.5,8.07C12.41,8.21 13.24,8.59 13.94,9.18C14.64,9.77 15.16,10.53 15.45,11.38C15.74,12.23 15.79,13.13 15.59,14C15.39,14.87 14.96,15.67 14.34,16.32L15.84,15.5Z";
1611
+ }
1612
+ if (browser.includes("safari")) {
1613
+ return "M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12A8,8 0 0,0 12,4M9.5,9.5L14,12L12,14L10.5,14.5L9.5,9.5M12,11A1,1 0 0,1 13,12A1,1 0 0,1 12,13A1,1 0 0,1 11,12A1,1 0 0,1 12,11Z";
1614
+ }
1615
+ if (browser.includes("edge") || browser.includes("edg")) {
1616
+ return "M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12C4,14.5 5.2,16.7 7.1,18C8,17 9.3,16.5 10.7,16.5C12.1,16.5 13.4,17 14.3,18C16.2,16.7 17.4,14.5 17.4,12C17.4,9.5 16.2,7.3 14.3,6C13.4,7 12.1,7.5 10.7,7.5C9.3,7.5 8,7 7.1,6C5.2,7.3 4,9.5 4,12M12,10A2,2 0 0,1 14,12A2,2 0 0,1 12,14A2,2 0 0,1 10,12A2,2 0 0,1 12,10Z";
1617
+ }
1618
+ if (browser.includes("opera")) {
1619
+ return "M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4C7.92,4 4.55,7.05 4.07,11H8.92C9.45,8.7 10.6,7 12,7C13.4,7 14.55,8.7 15.08,11H19.93C19.45,7.05 16.08,4 12,4M4.07,13C4.55,16.95 7.92,20 12,20C16.08,20 19.45,16.95 19.93,13H15.08C14.55,15.3 13.4,17 12,17C10.6,17 9.45,15.3 8.92,13H4.07Z";
1620
+ }
1621
+ if (platform.includes("tablet") || platform.includes("ipad")) {
1622
+ return "M19,18H5V6H19M21,4H3C1.89,4 1,4.89 1,6V18A2,2 0 0,0 3,20H21A2,2 0 0,0 23,18V6C23,4.89 22.1,4 21,4Z";
1623
+ }
1624
+ return "M17,19H7V5H17M17,1H7C5.89,1 5,1.89 5,3V21A2,2 0 0,0 7,23H17A2,2 0 0,0 19,21V3C19,1.89 18.1,1 17,1Z";
1625
+ };
1626
+ const hasFullName = computed(() => {
1627
+ return !!(user.value?.firstName && user.value?.lastName);
1628
+ });
1629
+ onMounted(() => document.addEventListener("click", closeMenu));
1630
+ onUnmounted(() => document.removeEventListener("click", closeMenu));
1631
+ return (_ctx, _cache) => {
1632
+ return openBlock(), createElementBlock(Fragment, null, [
1633
+ createVNode(Notification, {
1634
+ show: notification.value.show,
1635
+ message: notification.value.message,
1636
+ type: notification.value.type
1637
+ }, null, 8, ["show", "message", "type"]),
1638
+ unref(user) ? (openBlock(), createElementBlock("div", _hoisted_1$3, [
1639
+ createElementVNode("button", {
1640
+ class: "atm-profile-button",
1641
+ onClick: toggleMenu,
1642
+ ref_key: "buttonRef",
1643
+ ref: buttonRef
1644
+ }, [
1645
+ createElementVNode("div", {
1646
+ class: "atm-profile-avatar",
1647
+ style: normalizeStyle(unref(user)?.profileImage ? {} : { backgroundColor: atmPrimaryColor.value })
1648
+ }, [
1649
+ unref(user)?.profileImage ? (openBlock(), createElementBlock("img", {
1650
+ key: 0,
1651
+ src: unref(user).profileImage,
1652
+ alt: "Profile",
1653
+ class: "atm-profile-avatar-img"
1654
+ }, null, 8, _hoisted_2)) : hasFullName.value ? (openBlock(), createElementBlock("span", _hoisted_3, toDisplayString(userInitials.value), 1)) : (openBlock(), createElementBlock("svg", _hoisted_4, [..._cache[7] || (_cache[7] = [
1655
+ createElementVNode("path", {
1656
+ fill: "currentColor",
1657
+ d: "M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z"
1658
+ }, null, -1)
1659
+ ])]))
1660
+ ], 4),
1661
+ hasFullName.value ? (openBlock(), createElementBlock("span", _hoisted_5, toDisplayString(unref(user).firstName), 1)) : createCommentVNode("", true),
1662
+ (openBlock(), createElementBlock("svg", {
1663
+ class: normalizeClass(["atm-profile-arrow", { "atm-rotate": isDropdownOpen.value }]),
1664
+ viewBox: "0 0 24 24"
1665
+ }, [..._cache[8] || (_cache[8] = [
1666
+ createElementVNode("path", {
1667
+ fill: "currentColor",
1668
+ d: "M7,10L12,15L17,10H7Z"
1669
+ }, null, -1)
1670
+ ])], 2))
1671
+ ], 512),
1672
+ createVNode(Transition, { name: "atm-fade" }, {
1673
+ default: withCtx(() => [
1674
+ isDropdownOpen.value ? (openBlock(), createElementBlock("div", _hoisted_6, [
1675
+ createElementVNode("div", _hoisted_7, [
1676
+ createElementVNode("div", {
1677
+ class: "atm-profile-avatar large",
1678
+ style: normalizeStyle(unref(user)?.profileImage ? {} : { backgroundColor: atmPrimaryColor.value })
1679
+ }, [
1680
+ unref(user)?.profileImage ? (openBlock(), createElementBlock("img", {
1681
+ key: 0,
1682
+ src: unref(user).profileImage,
1683
+ alt: "Profile",
1684
+ class: "atm-profile-avatar-img"
1685
+ }, null, 8, _hoisted_8)) : hasFullName.value ? (openBlock(), createElementBlock("span", _hoisted_9, toDisplayString(userInitials.value), 1)) : (openBlock(), createElementBlock("svg", _hoisted_10, [..._cache[9] || (_cache[9] = [
1686
+ createElementVNode("path", {
1687
+ fill: "currentColor",
1688
+ d: "M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z"
1689
+ }, null, -1)
1690
+ ])]))
1691
+ ], 4),
1692
+ createElementVNode("div", _hoisted_11, [
1693
+ hasFullName.value ? (openBlock(), createElementBlock("p", _hoisted_12, toDisplayString(unref(user).firstName) + " " + toDisplayString(unref(user).lastName), 1)) : (openBlock(), createElementBlock("p", _hoisted_13, "Usuário")),
1694
+ createElementVNode("p", _hoisted_14, toDisplayString(unref(user).primaryEmailAddress), 1)
1695
+ ])
1696
+ ]),
1697
+ createElementVNode("div", { class: "atm-profile-options" }, [
1698
+ createElementVNode("button", {
1699
+ class: "atm-profile-option",
1700
+ onClick: openProfileModal,
1701
+ type: "button"
1702
+ }, [..._cache[10] || (_cache[10] = [
1703
+ createElementVNode("svg", {
1704
+ viewBox: "0 0 24 24",
1705
+ class: "atm-profile-icon"
1706
+ }, [
1707
+ createElementVNode("path", {
1708
+ fill: "currentColor",
1709
+ d: "M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z"
1710
+ })
1711
+ ], -1),
1712
+ createTextVNode(" Meu Perfil ", -1)
1713
+ ])]),
1714
+ createElementVNode("button", {
1715
+ class: "atm-profile-option",
1716
+ onClick: logoutUser,
1717
+ type: "button"
1718
+ }, [..._cache[11] || (_cache[11] = [
1719
+ createElementVNode("svg", {
1720
+ viewBox: "0 0 24 24",
1721
+ class: "atm-profile-icon"
1722
+ }, [
1723
+ createElementVNode("path", {
1724
+ fill: "currentColor",
1725
+ d: "M16,17V14H9V10H16V7L21,12L16,17M14,2A2,2 0 0,1 16,4V6H14V4H5V20H14V18H16V20A2,2 0 0,1 14,22H5A2,2 0 0,1 3,20V4A2,2 0 0,1 5,2H14Z"
1726
+ })
1727
+ ], -1),
1728
+ createTextVNode(" Sair ", -1)
1729
+ ])])
1730
+ ])
1731
+ ])) : createCommentVNode("", true)
1732
+ ]),
1733
+ _: 1
1734
+ }),
1735
+ isProfileModalOpen.value ? (openBlock(), createElementBlock("div", _hoisted_15, [
1736
+ createElementVNode("div", {
1737
+ class: "atm-profile-overlay",
1738
+ onClick: closeProfileModal
1739
+ }),
1740
+ createElementVNode("div", _hoisted_16, [
1741
+ createElementVNode("div", { class: "atm-profile-header" }, [
1742
+ createElementVNode("button", {
1743
+ onClick: closeProfileModal,
1744
+ class: "atm-profile-close",
1745
+ "aria-label": "Fechar"
1746
+ }, "×"),
1747
+ _cache[12] || (_cache[12] = createElementVNode("h2", {
1748
+ id: "profile-modal-title",
1749
+ class: "atm-profile-title"
1750
+ }, "Meu Perfil", -1))
1751
+ ]),
1752
+ createElementVNode("div", _hoisted_17, [
1753
+ createElementVNode("button", {
1754
+ onClick: _cache[0] || (_cache[0] = ($event) => activeTab.value = "geral"),
1755
+ class: normalizeClass(["atm-tab", { "atm-tab-active": activeTab.value === "geral" }])
1756
+ }, [..._cache[13] || (_cache[13] = [
1757
+ createElementVNode("svg", {
1758
+ viewBox: "0 0 24 24",
1759
+ class: "atm-tab-icon"
1760
+ }, [
1761
+ createElementVNode("path", {
1762
+ fill: "currentColor",
1763
+ d: "M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z"
1764
+ })
1765
+ ], -1),
1766
+ createTextVNode(" Geral ", -1)
1767
+ ])], 2),
1768
+ createElementVNode("button", {
1769
+ onClick: _cache[1] || (_cache[1] = ($event) => activeTab.value = "emails"),
1770
+ class: normalizeClass(["atm-tab", { "atm-tab-active": activeTab.value === "emails" }])
1771
+ }, [..._cache[14] || (_cache[14] = [
1772
+ createElementVNode("svg", {
1773
+ viewBox: "0 0 24 24",
1774
+ class: "atm-tab-icon"
1775
+ }, [
1776
+ createElementVNode("path", {
1777
+ fill: "currentColor",
1778
+ d: "M20,8L12,13L4,8V6L12,11L20,6M20,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V6C22,4.89 21.1,4 20,4Z"
1779
+ })
1780
+ ], -1),
1781
+ createTextVNode(" Emails ", -1)
1782
+ ])], 2),
1783
+ createElementVNode("button", {
1784
+ onClick: _cache[2] || (_cache[2] = ($event) => activeTab.value = "senha"),
1785
+ class: normalizeClass(["atm-tab", { "atm-tab-active": activeTab.value === "senha" }])
1786
+ }, [..._cache[15] || (_cache[15] = [
1787
+ createElementVNode("svg", {
1788
+ viewBox: "0 0 24 24",
1789
+ class: "atm-tab-icon"
1790
+ }, [
1791
+ createElementVNode("path", {
1792
+ fill: "currentColor",
1793
+ d: "M12,17A2,2 0 0,0 14,15C14,13.89 13.1,13 12,13A2,2 0 0,0 10,15A2,2 0 0,0 12,17M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V10C4,8.89 4.9,8 6,8H7V6A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,3A3,3 0 0,0 9,6V8H15V6A3,3 0 0,0 12,3Z"
1794
+ })
1795
+ ], -1),
1796
+ createTextVNode(" Senha ", -1)
1797
+ ])], 2),
1798
+ createElementVNode("button", {
1799
+ onClick: _cache[3] || (_cache[3] = ($event) => activeTab.value = "sessoes"),
1800
+ class: normalizeClass(["atm-tab", { "atm-tab-active": activeTab.value === "sessoes" }])
1801
+ }, [..._cache[16] || (_cache[16] = [
1802
+ createElementVNode("svg", {
1803
+ viewBox: "0 0 24 24",
1804
+ class: "atm-tab-icon"
1805
+ }, [
1806
+ createElementVNode("path", {
1807
+ fill: "currentColor",
1808
+ d: "M4,6H20V16H4M20,18A2,2 0 0,0 22,16V6C22,4.89 21.1,4 20,4H4C2.89,4 2,4.89 2,6V16A2,2 0 0,0 4,18H0V20H24V18H20Z"
1809
+ })
1810
+ ], -1),
1811
+ createTextVNode(" Sessões ", -1)
1812
+ ])], 2)
1813
+ ]),
1814
+ activeTab.value === "geral" ? (openBlock(), createElementBlock("div", _hoisted_18, [
1815
+ createElementVNode("div", {
1816
+ class: "atm-profile-avatar-large",
1817
+ style: normalizeStyle(unref(user)?.profileImage ? {} : { backgroundColor: atmPrimaryColor.value })
1818
+ }, [
1819
+ unref(user)?.profileImage ? (openBlock(), createElementBlock("img", {
1820
+ key: 0,
1821
+ src: unref(user).profileImage,
1822
+ alt: "Profile",
1823
+ class: "atm-profile-avatar-img"
1824
+ }, null, 8, _hoisted_19)) : hasFullName.value ? (openBlock(), createElementBlock("span", _hoisted_20, toDisplayString(userInitials.value), 1)) : (openBlock(), createElementBlock("svg", _hoisted_21, [..._cache[17] || (_cache[17] = [
1825
+ createElementVNode("path", {
1826
+ fill: "currentColor",
1827
+ d: "M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z"
1828
+ }, null, -1)
1829
+ ])]))
1830
+ ], 4),
1831
+ !isEditingProfile.value ? (openBlock(), createElementBlock("div", _hoisted_22, [
1832
+ createElementVNode("div", _hoisted_23, [
1833
+ _cache[18] || (_cache[18] = createElementVNode("span", { class: "atm-profile-info-label" }, "Nome", -1)),
1834
+ hasFullName.value ? (openBlock(), createElementBlock("span", _hoisted_24, toDisplayString(profileForm.value.firstName), 1)) : (openBlock(), createElementBlock("span", _hoisted_25, "Não informado"))
1835
+ ]),
1836
+ createElementVNode("div", _hoisted_26, [
1837
+ _cache[19] || (_cache[19] = createElementVNode("span", { class: "atm-profile-info-label" }, "Sobrenome", -1)),
1838
+ hasFullName.value ? (openBlock(), createElementBlock("span", _hoisted_27, toDisplayString(profileForm.value.lastName), 1)) : (openBlock(), createElementBlock("span", _hoisted_28, "Não informado"))
1839
+ ]),
1840
+ createElementVNode("div", _hoisted_29, [
1841
+ _cache[20] || (_cache[20] = createElementVNode("span", { class: "atm-profile-info-label" }, "Email Principal", -1)),
1842
+ createElementVNode("span", _hoisted_30, toDisplayString(profileForm.value.primaryEmailAddress), 1)
1843
+ ]),
1844
+ createElementVNode("div", { class: "atm-profile-info-row" }, [
1845
+ createElementVNode("button", {
1846
+ class: "atm-edit-profile-btn",
1847
+ onClick: startEditing,
1848
+ type: "button"
1849
+ }, [..._cache[21] || (_cache[21] = [
1850
+ createElementVNode("svg", {
1851
+ viewBox: "0 0 24 24",
1852
+ class: "atm-btn-icon"
1853
+ }, [
1854
+ createElementVNode("path", {
1855
+ fill: "currentColor",
1856
+ d: "M20.71,7.04C21.1,6.65 21.1,6 20.71,5.63L18.37,3.29C18,2.9 17.35,2.9 16.96,3.29L15.12,5.12L18.87,8.87M3,17.25V21H6.75L17.81,9.93L14.06,6.18L3,17.25Z"
1857
+ })
1858
+ ], -1),
1859
+ createTextVNode(" Editar Perfil ", -1)
1860
+ ])])
1861
+ ])
1862
+ ])) : (openBlock(), createElementBlock("div", _hoisted_31, [
1863
+ createElementVNode("div", _hoisted_32, [
1864
+ _cache[22] || (_cache[22] = createElementVNode("label", { class: "atm-input-label" }, "Nome", -1)),
1865
+ withDirectives(createElementVNode("input", {
1866
+ type: "text",
1867
+ class: "atm-input-field",
1868
+ "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => profileForm.value.firstName = $event),
1869
+ placeholder: "Digite seu nome"
1870
+ }, null, 512), [
1871
+ [vModelText, profileForm.value.firstName]
1872
+ ])
1873
+ ]),
1874
+ createElementVNode("div", _hoisted_33, [
1875
+ _cache[23] || (_cache[23] = createElementVNode("label", { class: "atm-input-label" }, "Sobrenome", -1)),
1876
+ withDirectives(createElementVNode("input", {
1877
+ type: "text",
1878
+ class: "atm-input-field",
1879
+ "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => profileForm.value.lastName = $event),
1880
+ placeholder: "Digite seu sobrenome"
1881
+ }, null, 512), [
1882
+ [vModelText, profileForm.value.lastName]
1883
+ ])
1884
+ ]),
1885
+ createElementVNode("div", { class: "atm-form-actions" }, [
1886
+ createElementVNode("button", {
1887
+ class: "atm-save-btn",
1888
+ onClick: updateProfile,
1889
+ type: "button"
1890
+ }, [..._cache[24] || (_cache[24] = [
1891
+ createElementVNode("svg", {
1892
+ viewBox: "0 0 24 24",
1893
+ class: "atm-btn-icon"
1894
+ }, [
1895
+ createElementVNode("path", {
1896
+ fill: "currentColor",
1897
+ d: "M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"
1898
+ })
1899
+ ], -1),
1900
+ createTextVNode(" Salvar ", -1)
1901
+ ])]),
1902
+ createElementVNode("button", {
1903
+ class: "atm-cancel-btn",
1904
+ onClick: cancelEditing,
1905
+ type: "button"
1906
+ }, [..._cache[25] || (_cache[25] = [
1907
+ createElementVNode("svg", {
1908
+ viewBox: "0 0 24 24",
1909
+ class: "atm-btn-icon"
1910
+ }, [
1911
+ createElementVNode("path", {
1912
+ fill: "currentColor",
1913
+ d: "M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"
1914
+ })
1915
+ ], -1),
1916
+ createTextVNode(" Cancelar ", -1)
1917
+ ])])
1918
+ ])
1919
+ ]))
1920
+ ])) : createCommentVNode("", true),
1921
+ activeTab.value === "emails" ? (openBlock(), createElementBlock("div", _hoisted_34, [
1922
+ createElementVNode("div", _hoisted_35, [
1923
+ createElementVNode("div", _hoisted_36, [
1924
+ _cache[27] || (_cache[27] = createElementVNode("label", { class: "atm-input-label" }, "Adicionar novo email", -1)),
1925
+ createElementVNode("div", _hoisted_37, [
1926
+ withDirectives(createElementVNode("input", {
1927
+ "onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => newEmail.value = $event),
1928
+ type: "email",
1929
+ class: "atm-input-field",
1930
+ placeholder: "novo@email.com"
1931
+ }, null, 512), [
1932
+ [vModelText, newEmail.value]
1933
+ ]),
1934
+ createElementVNode("button", {
1935
+ onClick: createEmailAddress,
1936
+ class: "atm-add-email-btn",
1937
+ type: "button"
1938
+ }, [..._cache[26] || (_cache[26] = [
1939
+ createElementVNode("svg", {
1940
+ viewBox: "0 0 24 24",
1941
+ class: "atm-btn-icon"
1942
+ }, [
1943
+ createElementVNode("path", {
1944
+ fill: "currentColor",
1945
+ d: "M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z"
1946
+ })
1947
+ ], -1)
1948
+ ])])
1949
+ ])
1950
+ ])
1951
+ ]),
1952
+ createElementVNode("div", _hoisted_38, [
1953
+ (openBlock(true), createElementBlock(Fragment, null, renderList(emailAddresses.value, (email) => {
1954
+ return openBlock(), createElementBlock("div", {
1955
+ key: email.id,
1956
+ class: "atm-email-item"
1957
+ }, [
1958
+ createElementVNode("div", _hoisted_39, [
1959
+ createElementVNode("div", _hoisted_40, [
1960
+ _cache[28] || (_cache[28] = createElementVNode("svg", {
1961
+ viewBox: "0 0 24 24",
1962
+ class: "atm-email-icon"
1963
+ }, [
1964
+ createElementVNode("path", {
1965
+ fill: "currentColor",
1966
+ d: "M20,8L12,13L4,8V6L12,11L20,6M20,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V6C22,4.89 21.1,4 20,4Z"
1967
+ })
1968
+ ], -1)),
1969
+ createElementVNode("span", null, toDisplayString(email.email_address), 1)
1970
+ ]),
1971
+ createElementVNode("div", _hoisted_41, [
1972
+ email.primary ? (openBlock(), createElementBlock("span", _hoisted_42, "Principal")) : createCommentVNode("", true),
1973
+ email.verified ? (openBlock(), createElementBlock("span", _hoisted_43, [..._cache[29] || (_cache[29] = [
1974
+ createElementVNode("svg", {
1975
+ viewBox: "0 0 24 24",
1976
+ class: "atm-badge-icon"
1977
+ }, [
1978
+ createElementVNode("path", {
1979
+ fill: "currentColor",
1980
+ d: "M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"
1981
+ })
1982
+ ], -1),
1983
+ createTextVNode(" Verificado ", -1)
1984
+ ])])) : (openBlock(), createElementBlock("span", _hoisted_44, [..._cache[30] || (_cache[30] = [
1985
+ createElementVNode("svg", {
1986
+ viewBox: "0 0 24 24",
1987
+ class: "atm-badge-icon"
1988
+ }, [
1989
+ createElementVNode("path", {
1990
+ fill: "currentColor",
1991
+ d: "M13,13H11V7H13M13,17H11V15H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z"
1992
+ })
1993
+ ], -1),
1994
+ createTextVNode(" Não verificado ", -1)
1995
+ ])]))
1996
+ ])
1997
+ ]),
1998
+ createElementVNode("div", _hoisted_45, [
1999
+ !email.verified ? (openBlock(), createElementBlock("button", {
2000
+ key: 0,
2001
+ onClick: ($event) => requestEmailVerification(email.id),
2002
+ class: "atm-verify-btn",
2003
+ type: "button"
2004
+ }, [..._cache[31] || (_cache[31] = [
2005
+ createElementVNode("svg", {
2006
+ viewBox: "0 0 24 24",
2007
+ class: "atm-btn-icon"
2008
+ }, [
2009
+ createElementVNode("path", {
2010
+ fill: "currentColor",
2011
+ d: "M12,1L3,5V11C3,16.55 6.84,21.74 12,23C17.16,21.74 21,16.55 21,11V5L12,1M10,17L6,13L7.41,11.59L10,14.17L16.59,7.58L18,9L10,17Z"
2012
+ })
2013
+ ], -1),
2014
+ createTextVNode(" Verificar ", -1)
2015
+ ])], 8, _hoisted_46)) : createCommentVNode("", true),
2016
+ !email.primary ? (openBlock(), createElementBlock("button", {
2017
+ key: 1,
2018
+ onClick: ($event) => deleteEmailAddress(email.id),
2019
+ class: "atm-delete-btn",
2020
+ type: "button"
2021
+ }, [..._cache[32] || (_cache[32] = [
2022
+ createElementVNode("svg", {
2023
+ viewBox: "0 0 24 24",
2024
+ class: "atm-btn-icon"
2025
+ }, [
2026
+ createElementVNode("path", {
2027
+ fill: "currentColor",
2028
+ d: "M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z"
2029
+ })
2030
+ ], -1),
2031
+ createTextVNode(" Remover ", -1)
2032
+ ])], 8, _hoisted_47)) : createCommentVNode("", true)
2033
+ ])
2034
+ ]);
2035
+ }), 128))
2036
+ ])
2037
+ ])) : createCommentVNode("", true),
2038
+ activeTab.value === "senha" ? (openBlock(), createElementBlock("div", _hoisted_48, [
2039
+ createElementVNode("div", { class: "atm-password-section" }, [
2040
+ _cache[34] || (_cache[34] = createElementVNode("div", { class: "atm-profile-info-row" }, [
2041
+ createElementVNode("span", { class: "atm-profile-info-label" }, "Redefinir Senha"),
2042
+ createElementVNode("span", { class: "atm-profile-info-value" }, " Enviaremos um link para redefinir sua senha no email principal ")
2043
+ ], -1)),
2044
+ createElementVNode("div", { class: "atm-profile-info-row" }, [
2045
+ createElementVNode("button", {
2046
+ class: "atm-reset-password-btn",
2047
+ onClick: sendResetPasswordLink,
2048
+ type: "button"
2049
+ }, [..._cache[33] || (_cache[33] = [
2050
+ createElementVNode("svg", {
2051
+ viewBox: "0 0 24 24",
2052
+ class: "atm-btn-icon"
2053
+ }, [
2054
+ createElementVNode("path", {
2055
+ fill: "currentColor",
2056
+ d: "M12,17A2,2 0 0,0 14,15C14,13.89 13.1,13 12,13A2,2 0 0,0 10,15A2,2 0 0,0 12,17M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V10C4,8.89 4.9,8 6,8H7V6A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,3A3,3 0 0,0 9,6V8H15V6A3,3 0 0,0 12,3Z"
2057
+ })
2058
+ ], -1),
2059
+ createTextVNode(" Resetar Senha ", -1)
2060
+ ])])
2061
+ ])
2062
+ ])
2063
+ ])) : createCommentVNode("", true),
2064
+ activeTab.value === "sessoes" ? (openBlock(), createElementBlock("div", _hoisted_49, [
2065
+ createElementVNode("div", _hoisted_50, [
2066
+ _cache[38] || (_cache[38] = createElementVNode("div", { class: "atm-sessions-info" }, [
2067
+ createElementVNode("p", { class: "atm-sessions-description" }, " Gerencie os dispositivos conectados à sua conta. Você pode encerrar sessões em dispositivos que não reconhece. ")
2068
+ ], -1)),
2069
+ createElementVNode("div", _hoisted_51, [
2070
+ (openBlock(true), createElementBlock(Fragment, null, renderList(sessions.value, (session) => {
2071
+ return openBlock(), createElementBlock("div", {
2072
+ key: session.id,
2073
+ class: "atm-session-item"
2074
+ }, [
2075
+ createElementVNode("div", _hoisted_52, [
2076
+ createElementVNode("div", _hoisted_53, [
2077
+ (openBlock(), createElementBlock("svg", _hoisted_54, [
2078
+ createElementVNode("path", {
2079
+ fill: "currentColor",
2080
+ d: getDeviceIcon(session.device)
2081
+ }, null, 8, _hoisted_55)
2082
+ ])),
2083
+ createElementVNode("div", _hoisted_56, [
2084
+ createElementVNode("div", _hoisted_57, [
2085
+ createElementVNode("span", null, toDisplayString(session.ip_address), 1),
2086
+ session.current === 1 ? (openBlock(), createElementBlock("span", _hoisted_58, "Atual")) : createCommentVNode("", true)
2087
+ ]),
2088
+ session.device.browser || session.device.platform ? (openBlock(), createElementBlock("div", _hoisted_59, [
2089
+ session.device.browser ? (openBlock(), createElementBlock("span", _hoisted_60, toDisplayString(session.device.browser) + toDisplayString(session.device.browser_version ? ` ${session.device.browser_version}` : ""), 1)) : createCommentVNode("", true),
2090
+ session.device.browser && session.device.platform ? (openBlock(), createElementBlock("span", _hoisted_61, " • ")) : createCommentVNode("", true),
2091
+ session.device.platform ? (openBlock(), createElementBlock("span", _hoisted_62, toDisplayString(session.device.platform), 1)) : createCommentVNode("", true)
2092
+ ])) : createCommentVNode("", true),
2093
+ createElementVNode("div", _hoisted_63, [
2094
+ createElementVNode("div", _hoisted_64, [
2095
+ _cache[35] || (_cache[35] = createElementVNode("span", { class: "atm-timestamp-label" }, "Iniciada:", -1)),
2096
+ createElementVNode("span", null, toDisplayString(formatDate(session.started_at)), 1)
2097
+ ]),
2098
+ createElementVNode("div", _hoisted_65, [
2099
+ _cache[36] || (_cache[36] = createElementVNode("span", { class: "atm-timestamp-label" }, "Última atividade:", -1)),
2100
+ createElementVNode("span", null, toDisplayString(formatDate(session.last_activity_at)), 1)
2101
+ ])
2102
+ ])
2103
+ ])
2104
+ ])
2105
+ ]),
2106
+ createElementVNode("div", _hoisted_66, [
2107
+ session.current !== 1 ? (openBlock(), createElementBlock("button", {
2108
+ key: 0,
2109
+ onClick: ($event) => closeSessionById(session.id),
2110
+ class: "atm-close-session-btn",
2111
+ type: "button"
2112
+ }, [..._cache[37] || (_cache[37] = [
2113
+ createElementVNode("svg", {
2114
+ viewBox: "0 0 24 24",
2115
+ class: "atm-btn-icon"
2116
+ }, [
2117
+ createElementVNode("path", {
2118
+ fill: "currentColor",
2119
+ d: "M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z"
2120
+ })
2121
+ ], -1),
2122
+ createTextVNode(" Encerrar ", -1)
2123
+ ])], 8, _hoisted_67)) : createCommentVNode("", true)
2124
+ ])
2125
+ ]);
2126
+ }), 128))
2127
+ ])
2128
+ ])
2129
+ ])) : createCommentVNode("", true)
2130
+ ])
2131
+ ])) : createCommentVNode("", true)
2132
+ ])) : createCommentVNode("", true)
2133
+ ], 64);
2134
+ };
2135
+ }
2136
+ });
2137
+ const _hoisted_1$2 = {
2138
+ key: 1,
2139
+ class: "atm-auth-buttons"
2140
+ };
2141
+ const _sfc_main$3 = /* @__PURE__ */ defineComponent({
2142
+ __name: "AuthSwitcher",
2143
+ setup(__props) {
2144
+ const { user } = useAuth();
2145
+ return (_ctx, _cache) => {
2146
+ return openBlock(), createElementBlock("div", null, [
2147
+ unref(user)?.id ? (openBlock(), createBlock(_sfc_main$4, { key: 0 })) : (openBlock(), createElementBlock("div", _hoisted_1$2, [
2148
+ createVNode(SignInButton),
2149
+ createVNode(SignUpButton)
2150
+ ]))
2151
+ ]);
2152
+ };
2153
+ }
2154
+ });
2155
+ const AuthSwitcher = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-0c63ecb8"]]);
2156
+ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
2157
+ __name: "SignOutButton",
2158
+ setup(__props) {
2159
+ useCssVars((_ctx) => ({
2160
+ "v2ec0f896": atmPrimaryColor.value
2161
+ }));
2162
+ const { logout, user } = useAuth();
2163
+ const { configurations } = useAtm();
2164
+ const atmPrimaryColor = computed(() => configurations.value?.design?.primaryColor);
2165
+ return (_ctx, _cache) => {
2166
+ return unref(user) ? (openBlock(), createElementBlock("button", {
2167
+ key: 0,
2168
+ onClick: _cache[0] || (_cache[0] = ($event) => unref(logout)()),
2169
+ class: "atm-logout-btn"
2170
+ }, " Sair ")) : createCommentVNode("", true);
2171
+ };
2172
+ }
2173
+ });
2174
+ const SignOutButton = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-7157f989"]]);
2175
+ const _hoisted_1$1 = { key: 0 };
2176
+ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
2177
+ __name: "SignedIn",
2178
+ setup(__props) {
2179
+ const { isSignedIn } = useAtm();
2180
+ return (_ctx, _cache) => {
2181
+ return unref(isSignedIn) ? (openBlock(), createElementBlock("div", _hoisted_1$1, [
2182
+ renderSlot(_ctx.$slots, "default")
2183
+ ])) : createCommentVNode("", true);
2184
+ };
2185
+ }
2186
+ });
2187
+ const _hoisted_1 = { key: 0 };
2188
+ const _sfc_main = /* @__PURE__ */ defineComponent({
2189
+ __name: "SignedOut",
2190
+ setup(__props) {
2191
+ const { isLoaded, isSignedIn } = useAtm();
2192
+ return (_ctx, _cache) => {
2193
+ return unref(isLoaded) && !unref(isSignedIn) ? (openBlock(), createElementBlock("div", _hoisted_1, [
2194
+ renderSlot(_ctx.$slots, "default")
2195
+ ])) : createCommentVNode("", true);
2196
+ };
2197
+ }
2198
+ });
2199
+ const fetchConfigurations = async (client, configurations) => {
2200
+ const response = await client.value.project().configurations();
2201
+ configurations.value = {
2202
+ project: {
2203
+ name: response.project.name,
2204
+ domain: response.project.domain
2205
+ },
2206
+ design: {
2207
+ primaryColor: response.design.primary_color,
2208
+ secondaryColor: response.design.secondary_color
2209
+ },
2210
+ username: {
2211
+ enable: response.username.enable,
2212
+ length: {
2213
+ min: response.username.length.min,
2214
+ max: response.username.length.max
2215
+ }
2216
+ },
2217
+ password: {
2218
+ enable: response.password.enable
2219
+ },
2220
+ firstName: {
2221
+ required: response.first_name.required
2222
+ },
2223
+ lastName: {
2224
+ required: response.last_name.required
2225
+ },
2226
+ register: {
2227
+ enable: response.register.enable
7
2228
  }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./components/AuthSwitcher.vue"), exports);
18
- __exportStar(require("./components/UserProfile.vue"), exports);
19
- __exportStar(require("./components/Buttons/SignInButton.vue"), exports);
20
- __exportStar(require("./components/Buttons/SignOutButton.vue"), exports);
21
- __exportStar(require("./components/Buttons/SignUpButton.vue"), exports);
22
- __exportStar(require("./components/Layout/SignedIn.vue"), exports);
23
- __exportStar(require("./components/Layout/SignedOut.vue"), exports);
24
- __exportStar(require("./composables/useAtm"), exports);
25
- __exportStar(require("./composables/useAtmClient"), exports);
26
- __exportStar(require("./composables/useAuth"), exports);
27
- __exportStar(require("./types/configurations.type"), exports);
28
- __exportStar(require("./types/user-attribute.type"), exports);
29
- __exportStar(require("./types/user.type"), exports);
30
- __exportStar(require("./types/session.type"), exports);
31
- __exportStar(require("./utils/device"), exports);
32
- __exportStar(require("./plugin"), exports);
2229
+ };
2230
+ };
2231
+ const atmPlugin = {
2232
+ install(app, pluginOptions) {
2233
+ const atmClient = new AtmClient({
2234
+ domain: pluginOptions.domain,
2235
+ publicKey: pluginOptions.publicKey,
2236
+ ssl: false
2237
+ });
2238
+ const client = ref(atmClient);
2239
+ const user = ref(null);
2240
+ const configurations = ref(null);
2241
+ const isSignedIn = computed(() => user.value !== void 0 && user.value !== null);
2242
+ const isLoaded = ref(false);
2243
+ Promise.all([
2244
+ fetchUser(client, user),
2245
+ fetchConfigurations(client, configurations)
2246
+ ]).then(() => isLoaded.value = true);
2247
+ app.provide("atm", {
2248
+ client,
2249
+ user,
2250
+ configurations,
2251
+ isSignedIn,
2252
+ isLoaded
2253
+ });
2254
+ }
2255
+ };
2256
+ export {
2257
+ AuthSwitcher,
2258
+ SignInButton,
2259
+ SignOutButton,
2260
+ SignUpButton,
2261
+ _sfc_main$1 as SignedIn,
2262
+ _sfc_main as SignedOut,
2263
+ _sfc_main$4 as UserProfile,
2264
+ atmPlugin,
2265
+ getDeviceToken,
2266
+ useAtm,
2267
+ useAtmClient,
2268
+ useAuth
2269
+ };
2270
+ //# sourceMappingURL=index.js.map