blob: d1037eae415d35e7349ddff20632caf86a51da30 [file] [log] [blame]
Ziwei Wang1455d972023-02-21 14:48:32 -05001/*
2 * Copyright (C) 2022 Savoir-faire Linux Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License as
6 * published by the Free Software Foundation; either version 3 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Affero General Public License for more details.
13 *
14 * You should have received a copy of the GNU Affero General Public
15 * License along with this program. If not, see
16 * <https://www.gnu.org/licenses/>.
17 */
18
Ziwei Wang0d8889d2023-02-21 17:15:00 -050019import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
Ziwei Wang1455d972023-02-21 14:48:32 -050020import axios from 'axios';
Ziwei Wang0d8889d2023-02-21 17:15:00 -050021import { AccessToken, IAdminConfigState } from 'jami-web-common';
Ziwei Wang3d633dd2023-02-21 16:57:48 -050022import { HttpStatusCode } from 'jami-web-common';
23import { useContext } from 'react';
24import { useNavigate } from 'react-router-dom';
Ziwei Wang1455d972023-02-21 14:48:32 -050025
Ziwei Wang3d633dd2023-02-21 16:57:48 -050026import { AlertSnackbarContext } from '../contexts/AlertSnackbarProvider';
Ziwei Wang1455d972023-02-21 14:48:32 -050027import { apiUrl } from '../utils/constants';
Ziwei Wang0d8889d2023-02-21 17:15:00 -050028
Ziwei Wang1455d972023-02-21 14:48:32 -050029export const useSetupAdminMutation = () => {
Ziwei Wang3d633dd2023-02-21 16:57:48 -050030 const navigate = useNavigate();
31 const { setAlertContent } = useContext(AlertSnackbarContext);
32
Ziwei Wang1455d972023-02-21 14:48:32 -050033 return useMutation({
34 mutationKey: ['admin', 'setup'],
35 mutationFn: async (password: string) => {
Ziwei Wangb7fd04c2023-02-28 16:53:30 -050036 const { data } = await axios.post('/admin/create', { password }, { baseURL: apiUrl });
Ziwei Wang1455d972023-02-21 14:48:32 -050037 return data;
38 },
Ziwei Wang3d633dd2023-02-21 16:57:48 -050039 onSuccess: () => {
40 //TODO: Do not login the admin for now in case we need to implement multi-factor authentication
41 navigate('/admin/login');
42 },
43 onError: (e: any) => {
44 if (e.response?.status === HttpStatusCode.BadRequest) {
45 setAlertContent({
46 messageI18nKey: 'login_invalid_password',
47 severity: 'error',
48 alertOpen: true,
49 });
50 } else {
51 setAlertContent({
52 messageI18nKey: 'unknown_error_alert',
53 severity: 'error',
54 alertOpen: true,
55 });
56 }
57 },
Ziwei Wang1455d972023-02-21 14:48:32 -050058 });
59};
60
61export const useLoginAdminMutation = () => {
Ziwei Wang3d633dd2023-02-21 16:57:48 -050062 const navigate = useNavigate();
63 const { setAlertContent } = useContext(AlertSnackbarContext);
64
Ziwei Wang1455d972023-02-21 14:48:32 -050065 return useMutation({
66 mutationKey: ['admin', 'login'],
67 mutationFn: async (password: string) => {
Ziwei Wangb7fd04c2023-02-28 16:53:30 -050068 const { data } = await axios.post<AccessToken>('/admin/login', { password }, { baseURL: apiUrl });
Ziwei Wang1455d972023-02-21 14:48:32 -050069 return data;
70 },
Ziwei Wang3d633dd2023-02-21 16:57:48 -050071 onSuccess: (data) => {
72 localStorage.setItem('adminAccessToken', data.accessToken);
73 navigate('/admin');
74 },
75 onError: (e: any) => {
76 if (e.response?.status === HttpStatusCode.Forbidden) {
77 setAlertContent({
78 messageI18nKey: 'admin_page_setup_not_complete',
79 severity: 'error',
80 alertOpen: true,
81 });
82 } else if (e.response?.status === HttpStatusCode.BadRequest) {
83 setAlertContent({
84 messageI18nKey: 'password_input_helper_text_empty',
85 severity: 'error',
86 alertOpen: true,
87 });
88 } else if (e.response?.status === HttpStatusCode.Unauthorized) {
89 setAlertContent({
90 messageI18nKey: 'login_invalid_password',
91 severity: 'error',
92 alertOpen: true,
93 });
94 } else {
95 setAlertContent({
96 messageI18nKey: 'unknown_error_alert',
97 severity: 'error',
98 alertOpen: true,
99 });
100 }
101 },
Ziwei Wang1455d972023-02-21 14:48:32 -0500102 });
103};
104
Ziwei Wang3d633dd2023-02-21 16:57:48 -0500105//For non-react components that need to get the admin setup status
106export const checkAdminSetupStatus = async () => {
Ziwei Wang1455d972023-02-21 14:48:32 -0500107 try {
Ziwei Wangb7fd04c2023-02-28 16:53:30 -0500108 const { data } = await axios.get<{ isSetupComplete: boolean }>('/admin/check', { baseURL: apiUrl });
Ziwei Wang1455d972023-02-21 14:48:32 -0500109 return data.isSetupComplete;
110 } catch (e) {
Ziwei Wang3d633dd2023-02-21 16:57:48 -0500111 console.log(e);
Ziwei Wang1455d972023-02-21 14:48:32 -0500112 }
Ziwei Wang3d633dd2023-02-21 16:57:48 -0500113};
114
115//For react components that can invoke hooks
116export const useCheckAdminSetupStatusQuery = () => {
117 return useQuery({
118 queryKey: ['admin', 'status'],
119 queryFn: async () => {
Ziwei Wangb7fd04c2023-02-28 16:53:30 -0500120 const { data } = await axios.get<{ isSetupComplete: boolean }>('/admin/check', { baseURL: apiUrl });
Ziwei Wang3d633dd2023-02-21 16:57:48 -0500121 return data.isSetupComplete;
122 },
123 });
124};
Ziwei Wang0d8889d2023-02-21 17:15:00 -0500125
126export const useGetAdminConfigQuery = () => {
127 const token = localStorage.getItem('adminAccessToken');
128 const navigate = useNavigate();
129 const { setAlertContent } = useContext(AlertSnackbarContext);
130
131 return useQuery({
132 queryKey: ['admin', 'config'],
133 queryFn: async () => {
134 const { data } = await axios.get('/admin/config', {
135 baseURL: apiUrl,
136 //TODO: create a intercepted axios instance for auth-required requests
137 headers: {
138 Authorization: `Bearer ${token}`,
139 },
140 });
141 return data;
142 },
143 onError: (e: any) => {
144 if (e.response.status === HttpStatusCode.Unauthorized) {
145 localStorage.removeItem('adminAccessToken');
146 navigate('/admin/login');
147 } else {
148 setAlertContent({
149 messageI18nKey: 'unknown_error_alert',
150 severity: 'error',
151 alertOpen: true,
152 });
153 }
154 },
155 });
156};
157
158export const useUpdateAdminConfigMutation = () => {
159 const token = localStorage.getItem('adminAccessToken');
160 const navigate = useNavigate();
161 const { setAlertContent } = useContext(AlertSnackbarContext);
162 const queryClient = useQueryClient();
163
164 return useMutation({
165 mutationFn: async (adminConfig: Partial<IAdminConfigState>) => {
166 const response = await axios.patch('/admin/config', adminConfig, {
167 baseURL: apiUrl,
168 headers: {
169 Authorization: `Bearer ${token}`,
170 },
171 });
172 return response;
173 },
174 onSuccess: () => {
175 queryClient.invalidateQueries({ queryKey: ['admin', 'config'] });
176 },
177 onError: (e: any) => {
178 if (e.repsponse.status === HttpStatusCode.Unauthorized) {
179 localStorage.removeItem('adminAccessToken');
180 navigate('/admin/login');
181 } else {
182 setAlertContent({
183 messageI18nKey: 'unknown_error_alert',
184 severity: 'error',
185 alertOpen: true,
186 });
187 }
188 },
189 });
190};