1import { LOGIN_PAGE, router } from "@/router";
2import { call, createResource } from "frappe-ui";
3import { defineStore } from "pinia";
4import { computed, ComputedRef, Ref, ref } from "vue";
5
6const URI_LOGOUT = "logout";
7const URI_USER_INFO = "opendesk.api.auth.get_user";
8
9/**
10 * This is supposed to be the entry point of authentication. This will be
11 * called from router itself. Hence the router instance from `useRouter()` will
12 * not be available. All Authentication related logic should go in this file.
13 * Some of these might contain async methods, beware. */
14export const useAuthStore = defineStore("auth", () => {
15 const userInfo = createResource({
16 url: URI_USER_INFO,
17 });
18 const init = async () => {
19 if (userInfo.fetched) return;
20 await userInfo.fetch();
21 };
22 const reloadUser = userInfo.reload;
23
24 const user__ = computed(() => userInfo.data || {});
25 const hasDeskAccess: ComputedRef<boolean> = computed(
26 () => user__.value.has_desk_access
27 );
28 const isAdmin: ComputedRef<boolean> = computed(() => user__.value.is_admin);
29 const isAgent: ComputedRef<boolean> = computed(() => user__.value.is_agent);
30 const hasAgentRecord: ComputedRef<boolean> = computed(
31 () => user__.value.has_agent_record
32 );
33 const isManager: ComputedRef<boolean> = computed(
34 () => user__.value.is_manager
35 );
36
37 const userId: ComputedRef<string> = computed(() => user__.value.user_id);
38 const userImage: ComputedRef<string> = computed(
39 () => user__.value.user_image
40 );
41 const userFirstName: ComputedRef<string> = computed(
42 () => user__.value.user_first_name
43 );
44 const userName: ComputedRef<string> = computed(() => user__.value.user_name);
45 const username: ComputedRef<string> = computed(() => user__.value.username);
46 const availability: ComputedRef<string> = computed(
47 () => user__.value.availability || ""
48 );
49 const availabilityChangedOn: ComputedRef<string> = computed(
50 () => user__.value.availability_changed_on || ""
51 );
52 const availabilityChangedBy: ComputedRef<string> = computed(
53 () => user__.value.availability_changed_by || ""
54 );
55 const timezone: ComputedRef<string> = computed(() => user__.value.time_zone);
56 const userTeams: ComputedRef<string[]> = computed(
57 () => user__.value.user_teams
58 );
59 const language: ComputedRef<string> = computed(() => user__.value.language);
60 const personaCaptured: ComputedRef<boolean> = computed(
61 () => !!user__.value.persona_captured
62 );
63
64 function sessionUser() {
65 const cookies = new URLSearchParams(document.cookie.split("; ").join("&"));
66 let _sessionUser = cookies.get("user_id");
67 if (_sessionUser === "Guest") {
68 _sessionUser = null;
69 }
70 return _sessionUser;
71 }
72 const user: Ref<string> = ref(sessionUser());
73 const isLoggedIn: ComputedRef<boolean> = computed(() => !!user.value);
74 // No in-SPA login on purpose: the full-page login round trip is what keeps
75 // module-scope userStorage keys in sync with the session cookie.
76
77 function logout() {
78 user.value = null;
79 call(URI_LOGOUT).then(() => {
80 window.location.href = LOGIN_PAGE;
81 });
82 }
83
84 return {
85 hasDeskAccess,
86 init,
87 isAdmin,
88 isAgent,
89 hasAgentRecord,
90 isManager,
91 isLoggedIn,
92 reloadUser,
93 userFirstName,
94 userId,
95 userImage,
96 userName,
97 username,
98 availability,
99 availabilityChangedOn,
100 availabilityChangedBy,
101 timezone,
102 userTeams,
103 language,
104 personaCaptured,
105 user,
106 logout,
107 };
108});
109