adminforth 2.27.0-next.72 → 2.27.0-next.73

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.
@@ -12,12 +12,113 @@ import type { AdminForthActionFront, AdminForthResourceColumnInputCommon, AdminF
12
12
  import { i18nInstance } from '../i18n'
13
13
  import { useI18n } from 'vue-i18n';
14
14
  import { onBeforeRouteLeave } from 'vue-router';
15
+ import { reconnect } from '@/websocket';
15
16
 
16
17
 
17
18
 
18
19
  const LS_LANG_KEY = `afLanguage`;
19
20
  const MAX_CONSECUTIVE_EMPTY_RESULTS = 2;
20
21
  const ITEMS_PER_PAGE_LIMIT = 100;
22
+ const AUTOLOGIN_QUERY_PARAM = 'autologin';
23
+
24
+ export function getAutologinCredentials(autologin: unknown): { username: string, password: string } | null {
25
+ if (typeof autologin !== 'string') {
26
+ return null;
27
+ }
28
+
29
+ const separatorIndex = autologin.indexOf(':');
30
+ if (separatorIndex === -1) {
31
+ return null;
32
+ }
33
+
34
+ return {
35
+ username: autologin.slice(0, separatorIndex),
36
+ password: autologin.slice(separatorIndex + 1),
37
+ };
38
+ }
39
+
40
+ function buildLoginRedirectQuery() {
41
+ const { path, query } = router.currentRoute.value;
42
+ const nextQuery = new URLSearchParams();
43
+
44
+ for (const [key, rawValue] of Object.entries(query)) {
45
+ if (key === AUTOLOGIN_QUERY_PARAM || rawValue == null) {
46
+ continue;
47
+ }
48
+
49
+ if (Array.isArray(rawValue)) {
50
+ rawValue.forEach((value) => {
51
+ if (value != null) {
52
+ nextQuery.append(key, value);
53
+ }
54
+ });
55
+ continue;
56
+ }
57
+
58
+ nextQuery.set(key, rawValue);
59
+ }
60
+
61
+ const next = nextQuery.size > 0 ? `${path}?${nextQuery.toString()}` : path;
62
+ const autologin = typeof query[AUTOLOGIN_QUERY_PARAM] === 'string'
63
+ ? query[AUTOLOGIN_QUERY_PARAM]
64
+ : undefined;
65
+
66
+ return {
67
+ next,
68
+ autologin,
69
+ };
70
+ }
71
+
72
+ async function tryAutologin(autologin: string): Promise<boolean> {
73
+ const credentials = getAutologinCredentials(autologin);
74
+ if (!credentials) {
75
+ return false;
76
+ }
77
+
78
+ const response = await fetch(`${import.meta.env.VITE_ADMINFORTH_PUBLIC_PATH || ''}/adminapi/v1/login`, {
79
+ method: 'POST',
80
+ headers: {
81
+ 'Content-Type': 'application/json',
82
+ 'accept-language': localStorage.getItem(LS_LANG_KEY) || 'en',
83
+ },
84
+ body: JSON.stringify({
85
+ username: credentials.username,
86
+ password: credentials.password,
87
+ rememberMe: false,
88
+ }),
89
+ });
90
+
91
+ const loginResponse = await response.json();
92
+ if (loginResponse?.error) {
93
+ return false;
94
+ }
95
+
96
+ const userStore = useUserStore();
97
+ const coreStore = useCoreStore();
98
+ userStore.authorize();
99
+ reconnect();
100
+ await coreStore.fetchMenuAndResource();
101
+ return !!coreStore.adminUser;
102
+ }
103
+
104
+ export async function redirectToLogin() {
105
+ const currentPath = router.currentRoute.value.path;
106
+ const homeRoute = router.getRoutes().find(route => route.name === 'home');
107
+ const homePagePath = (homeRoute?.redirect as string) || '/';
108
+ const { next, autologin } = buildLoginRedirectQuery();
109
+
110
+ if (autologin && await tryAutologin(autologin)) {
111
+ return;
112
+ }
113
+
114
+ const query: Record<string, string> = {};
115
+
116
+ if (currentPath !== '/login' && currentPath !== homePagePath) {
117
+ query.next = next;
118
+ }
119
+
120
+ await router.push({ name: 'login', query });
121
+ }
21
122
 
22
123
  export async function callApi({path, method, body, headers, silentError = false, abortSignal}: {
23
124
  path: string, method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'
@@ -43,20 +144,7 @@ export async function callApi({path, method, body, headers, silentError = false,
43
144
  if (r.status == 401 ) {
44
145
  useUserStore().unauthorize();
45
146
  useCoreStore().resetAdminUser();
46
- const currentPath = router.currentRoute.value.path;
47
- const homeRoute = router.getRoutes().find(route => route.name === 'home');
48
- const homePagePath = (homeRoute?.redirect as string) || '/';
49
- let next = '';
50
- if (currentPath !== '/login' && currentPath !== homePagePath) {
51
- if (Object.keys(router.currentRoute.value.query).length > 0) {
52
- next = currentPath + '?' + Object.entries(router.currentRoute.value.query).map(([key, value]) => `${key}=${value}`).join('&');
53
- } else {
54
- next = currentPath;
55
- }
56
- await router.push({ name: 'login', query: { next: next } });
57
- } else {
58
- await router.push({ name: 'login' });
59
- }
147
+ await redirectToLogin();
60
148
  return null;
61
149
  }
62
150
  return await r.json();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adminforth",
3
- "version": "2.27.0-next.72",
3
+ "version": "2.27.0-next.73",
4
4
  "description": "OpenSource Vue3 powered forth-generation admin panel",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",