Compare commits
7 Commits
b42da50306
...
95c330568d
Author | SHA1 | Date | |
---|---|---|---|
95c330568d | |||
900d314a95 | |||
0d8a3b1b39 | |||
4b7396c210 | |||
d4e2cbdd4f | |||
5024ac8151 | |||
3bf08c5933 |
@ -283,3 +283,36 @@ func (h *AdminHandler) UpdateApiService(w http.ResponseWriter, r *http.Request)
|
|||||||
web.Error(w, "failed to send updated api service", http.StatusInternalServerError)
|
web.Error(w, "failed to send updated api service", http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *AdminHandler) ToggleApiService(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
serviceId := chi.URLParam(r, "id")
|
||||||
|
parsed, err := uuid.Parse(serviceId)
|
||||||
|
if err != nil {
|
||||||
|
web.Error(w, "provided service id is not valid", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
service, err := h.repo.GetApiServiceId(r.Context(), parsed)
|
||||||
|
if err != nil {
|
||||||
|
web.Error(w, "service with provided id not found", http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if service.IsActive {
|
||||||
|
log.Println("INFO: Service is active. Deactivating...")
|
||||||
|
err = h.repo.DeactivateApiService(r.Context(), service.ClientID)
|
||||||
|
} else {
|
||||||
|
log.Println("INFO: Service is inactive. Activating...")
|
||||||
|
err = h.repo.ActivateApiService(r.Context(), service.ClientID)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("ERR: Failed to toggle api service (cid: %s): %v\n", service.ClientID, err)
|
||||||
|
web.Error(w, "failed to toggle api service", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
}
|
||||||
|
@ -30,5 +30,6 @@ func (h *AdminHandler) RegisterRoutes(router chi.Router) {
|
|||||||
r.Post("/api-services", h.AddApiService)
|
r.Post("/api-services", h.AddApiService)
|
||||||
r.Patch("/api-services/{id}", h.RegenerateApiServiceSecret)
|
r.Patch("/api-services/{id}", h.RegenerateApiServiceSecret)
|
||||||
r.Put("/api-services/{id}", h.RegenerateApiServiceSecret)
|
r.Put("/api-services/{id}", h.RegenerateApiServiceSecret)
|
||||||
|
r.Patch("/api-services/toggle/{id}", h.ToggleApiService)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,18 @@ import (
|
|||||||
"github.com/jackc/pgx/v5/pgtype"
|
"github.com/jackc/pgx/v5/pgtype"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const activateApiService = `-- name: ActivateApiService :exec
|
||||||
|
UPDATE api_services
|
||||||
|
SET is_active = true,
|
||||||
|
updated_at = NOW()
|
||||||
|
WHERE client_id = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) ActivateApiService(ctx context.Context, clientID string) error {
|
||||||
|
_, err := q.db.Exec(ctx, activateApiService, clientID)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
const createApiService = `-- name: CreateApiService :one
|
const createApiService = `-- name: CreateApiService :one
|
||||||
INSERT INTO api_services (
|
INSERT INTO api_services (
|
||||||
client_id, client_secret, name, description, redirect_uris, scopes, grant_types, is_active
|
client_id, client_secret, name, description, redirect_uris, scopes, grant_types, is_active
|
||||||
|
@ -38,6 +38,12 @@ SET is_active = false,
|
|||||||
updated_at = NOW()
|
updated_at = NOW()
|
||||||
WHERE client_id = $1;
|
WHERE client_id = $1;
|
||||||
|
|
||||||
|
-- name: ActivateApiService :exec
|
||||||
|
UPDATE api_services
|
||||||
|
SET is_active = true,
|
||||||
|
updated_at = NOW()
|
||||||
|
WHERE client_id = $1;
|
||||||
|
|
||||||
-- name: UpdateClientSecret :exec
|
-- name: UpdateClientSecret :exec
|
||||||
UPDATE api_services
|
UPDATE api_services
|
||||||
SET client_secret = $2,
|
SET client_secret = $2,
|
||||||
|
@ -55,3 +55,12 @@ export const getApiService = async (id: string): Promise<ApiService> => {
|
|||||||
|
|
||||||
return response.data;
|
return response.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const patchToggleApiService = async (id: string): Promise<void> => {
|
||||||
|
const response = await axios.patch(`/api/v1/admin/api-services/toggle/${id}`);
|
||||||
|
|
||||||
|
if (response.status !== 200 && response.status !== 201)
|
||||||
|
throw await handleApiError(response);
|
||||||
|
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
@ -2,7 +2,7 @@ import Breadcrumbs from "@/components/ui/breadcrumbs";
|
|||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { useAdmin } from "@/store/admin";
|
import { useAdmin } from "@/store/admin";
|
||||||
import { useEffect, type FC } from "react";
|
import { useCallback, useEffect, type FC } from "react";
|
||||||
import { Link, useParams } from "react-router";
|
import { Link, useParams } from "react-router";
|
||||||
|
|
||||||
const InfoCard = ({
|
const InfoCard = ({
|
||||||
@ -29,6 +29,9 @@ const ViewApiServicePage: FC = () => {
|
|||||||
|
|
||||||
const loadService = useAdmin((state) => state.fetchApiService);
|
const loadService = useAdmin((state) => state.fetchApiService);
|
||||||
|
|
||||||
|
const toggling = useAdmin((state) => state.togglingApiService);
|
||||||
|
const toggle = useAdmin((state) => state.toggleApiService);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (typeof serviceId === "string") loadService(serviceId);
|
if (typeof serviceId === "string") loadService(serviceId);
|
||||||
}, [loadService, serviceId]);
|
}, [loadService, serviceId]);
|
||||||
@ -181,7 +184,8 @@ const ViewApiServicePage: FC = () => {
|
|||||||
? "text-red-400 hover:text-red-500"
|
? "text-red-400 hover:text-red-500"
|
||||||
: "text-green-400 hover:text-green-500"
|
: "text-green-400 hover:text-green-500"
|
||||||
}
|
}
|
||||||
onClick={() => {}}
|
onClick={toggle}
|
||||||
|
loading={toggling}
|
||||||
>
|
>
|
||||||
{apiService.is_active ? "Disable" : "Enable"}
|
{apiService.is_active ? "Disable" : "Enable"}
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
getApiService,
|
getApiService,
|
||||||
getApiServices,
|
getApiServices,
|
||||||
|
patchToggleApiService,
|
||||||
postApiService,
|
postApiService,
|
||||||
type CreateApiServiceRequest,
|
type CreateApiServiceRequest,
|
||||||
} from "@/api/admin/apiServices";
|
} from "@/api/admin/apiServices";
|
||||||
@ -21,9 +22,12 @@ interface IAdminState {
|
|||||||
fetchApiService: (id: string) => Promise<void>;
|
fetchApiService: (id: string) => Promise<void>;
|
||||||
createApiService: (req: CreateApiServiceRequest) => Promise<void>;
|
createApiService: (req: CreateApiServiceRequest) => Promise<void>;
|
||||||
resetCredentials: () => void;
|
resetCredentials: () => void;
|
||||||
|
|
||||||
|
togglingApiService: boolean;
|
||||||
|
toggleApiService: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useAdmin = create<IAdminState>((set) => ({
|
export const useAdmin = create<IAdminState>((set, get) => ({
|
||||||
apiServices: [],
|
apiServices: [],
|
||||||
loadingApiServices: false,
|
loadingApiServices: false,
|
||||||
|
|
||||||
@ -33,6 +37,8 @@ export const useAdmin = create<IAdminState>((set) => ({
|
|||||||
viewApiService: null,
|
viewApiService: null,
|
||||||
fetchingApiService: false,
|
fetchingApiService: false,
|
||||||
|
|
||||||
|
togglingApiService: false,
|
||||||
|
|
||||||
resetCredentials: () => set({ createdCredentials: null }),
|
resetCredentials: () => set({ createdCredentials: null }),
|
||||||
|
|
||||||
fetchApiServices: async () => {
|
fetchApiServices: async () => {
|
||||||
@ -61,6 +67,22 @@ export const useAdmin = create<IAdminState>((set) => ({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
toggleApiService: async () => {
|
||||||
|
const viewService = get().viewApiService;
|
||||||
|
if (!viewService) return;
|
||||||
|
|
||||||
|
set({ togglingApiService: true });
|
||||||
|
|
||||||
|
try {
|
||||||
|
await patchToggleApiService(viewService.id);
|
||||||
|
get().fetchApiService(viewService.id);
|
||||||
|
} catch (err) {
|
||||||
|
console.log("ERR: Failed to toggle service:", err);
|
||||||
|
} finally {
|
||||||
|
set({ togglingApiService: false });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
createApiService: async (req: CreateApiServiceRequest) => {
|
createApiService: async (req: CreateApiServiceRequest) => {
|
||||||
set({ creatingApiService: true });
|
set({ creatingApiService: true });
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user