refactor: update storage-related API and components for improved functionality
This commit is contained in:
parent
7b619e54db
commit
7f93bdeb98
10 changed files with 165 additions and 102 deletions
|
|
@ -65,9 +65,10 @@ ENV TILES_URL="localhost:6379"
|
||||||
ENV SKEBBY_USER="mock"
|
ENV SKEBBY_USER="mock"
|
||||||
ENV SKEBBY_PASS="mock"
|
ENV SKEBBY_PASS="mock"
|
||||||
ENV REVALIDATION_SECRET="mock"
|
ENV REVALIDATION_SECRET="mock"
|
||||||
|
ENV STORAGE_URL="mock"
|
||||||
ENV STORAGE_TOKEN="mock"
|
ENV STORAGE_TOKEN="mock"
|
||||||
|
|
||||||
|
#TODO remove variabili non necessarie al build tanto la validazione viene saltata
|
||||||
RUN SKIP_ENV_VALIDATION=1 npm run build
|
RUN SKIP_ENV_VALIDATION=1 npm run build
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -132,6 +133,8 @@ ENV SKEBBY_USER=$SKEBBY_USER
|
||||||
ARG SKEBBY_PASS
|
ARG SKEBBY_PASS
|
||||||
ENV SKEBBY_PASS=$SKEBBY_PASS
|
ENV SKEBBY_PASS=$SKEBBY_PASS
|
||||||
ENV REVALIDATION_SECRET="SWKpgaaLfsyeqV1eOT0WG7TUFBewir8kJXure3O37ki8Lt4Z4IiEgBW4zPHDdM5c"
|
ENV REVALIDATION_SECRET="SWKpgaaLfsyeqV1eOT0WG7TUFBewir8kJXure3O37ki8Lt4Z4IiEgBW4zPHDdM5c"
|
||||||
|
ARG STORAGE_URL
|
||||||
|
ENV STORAGE_URL=$STORAGE_URL
|
||||||
ARG STORAGE_TOKEN
|
ARG STORAGE_TOKEN
|
||||||
ENV STORAGE_TOKEN=$STORAGE_TOKEN
|
ENV STORAGE_TOKEN=$STORAGE_TOKEN
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,10 +59,6 @@ async function createNextConfig(): Promise<NextConfig> {
|
||||||
reactStrictMode: true,
|
reactStrictMode: true,
|
||||||
rewrites: async () => {
|
rewrites: async () => {
|
||||||
return [
|
return [
|
||||||
{
|
|
||||||
source: "/storage-api/:slug*",
|
|
||||||
destination: `http://localhost:8080/:slug*?token=${env.STORAGE_TOKEN}`,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
destination: env.NODE_ENV === "production" ? "/404" : "/api/panel",
|
destination: env.NODE_ENV === "production" ? "/404" : "/api/panel",
|
||||||
source: "/api/panel",
|
source: "/api/panel",
|
||||||
|
|
@ -71,32 +67,6 @@ async function createNextConfig(): Promise<NextConfig> {
|
||||||
destination: `${env.BACKENDSERVER_URL}/images/get/:slug*`,
|
destination: `${env.BACKENDSERVER_URL}/images/get/:slug*`,
|
||||||
source: "/go-api/images/get/:slug*",
|
source: "/go-api/images/get/:slug*",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
destination: `${env.BACKENDSERVER_URL}/storage/get/:slug*`,
|
|
||||||
has: [
|
|
||||||
{ key: "access_token", type: "cookie" },
|
|
||||||
{
|
|
||||||
key: "token",
|
|
||||||
type: "query",
|
|
||||||
value:
|
|
||||||
"(?<token>^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$)",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
source: "/go-api/storage/get/:slug*",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
destination: `${env.BACKENDSERVER_URL}/storage/upload:slug*`,
|
|
||||||
has: [
|
|
||||||
{ key: "access_token", type: "cookie" },
|
|
||||||
{
|
|
||||||
key: "token",
|
|
||||||
type: "query",
|
|
||||||
value:
|
|
||||||
"(?<token>^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$)",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
source: "/go-api/storage/upload:slug*",
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -500,14 +500,15 @@ const ContrattoSection = ({
|
||||||
|
|
||||||
const { data: files, isLoading } = api.storage.getAll.useQuery();
|
const { data: files, isLoading } = api.storage.getAll.useQuery();
|
||||||
|
|
||||||
const { mutate: setUserStorage } = api.storage.addUserStorage.useMutation({
|
const { mutate: setUserStorage } =
|
||||||
onSuccess: async () => {
|
api.storage.addUserStorageEntry.useMutation({
|
||||||
await utils.storage.retrieveUserFileData.invalidate({
|
onSuccess: async () => {
|
||||||
userId,
|
await utils.storage.retrieveUserFileData.invalidate({
|
||||||
});
|
userId,
|
||||||
await utils.storage.getAll.invalidate();
|
});
|
||||||
},
|
await utils.storage.getAll.invalidate();
|
||||||
});
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
handleUpdate({
|
handleUpdate({
|
||||||
|
|
@ -592,14 +593,15 @@ const RicevutaSection = ({
|
||||||
|
|
||||||
const { data: files, isLoading } = api.storage.getAll.useQuery();
|
const { data: files, isLoading } = api.storage.getAll.useQuery();
|
||||||
|
|
||||||
const { mutate: setUserStorage } = api.storage.addUserStorage.useMutation({
|
const { mutate: setUserStorage } =
|
||||||
onSuccess: async () => {
|
api.storage.addUserStorageEntry.useMutation({
|
||||||
await utils.storage.retrieveUserFileData.invalidate({
|
onSuccess: async () => {
|
||||||
userId,
|
await utils.storage.retrieveUserFileData.invalidate({
|
||||||
});
|
userId,
|
||||||
await utils.storage.getAll.invalidate();
|
});
|
||||||
},
|
await utils.storage.getAll.invalidate();
|
||||||
});
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
handleUpdate({
|
handleUpdate({
|
||||||
|
|
@ -757,14 +759,15 @@ const DocSection = ({
|
||||||
|
|
||||||
const { data: files, isLoading } = api.storage.getAll.useQuery();
|
const { data: files, isLoading } = api.storage.getAll.useQuery();
|
||||||
|
|
||||||
const { mutate: setUserStorage } = api.storage.addUserStorage.useMutation({
|
const { mutate: setUserStorage } =
|
||||||
onSuccess: async () => {
|
api.storage.addUserStorageEntry.useMutation({
|
||||||
await utils.storage.retrieveUserFileData.invalidate({
|
onSuccess: async () => {
|
||||||
userId,
|
await utils.storage.retrieveUserFileData.invalidate({
|
||||||
});
|
userId,
|
||||||
await utils.storage.getAll.invalidate();
|
});
|
||||||
},
|
await utils.storage.getAll.invalidate();
|
||||||
});
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (isLoading) return <LoadingPage />;
|
if (isLoading) return <LoadingPage />;
|
||||||
if (files === undefined) {
|
if (files === undefined) {
|
||||||
|
|
|
||||||
|
|
@ -36,13 +36,8 @@ import {
|
||||||
} from "~/components/ui/dropdown-menu";
|
} from "~/components/ui/dropdown-menu";
|
||||||
import { Input } from "~/components/ui/input";
|
import { Input } from "~/components/ui/input";
|
||||||
import { cn } from "~/lib/utils";
|
import { cn } from "~/lib/utils";
|
||||||
import { useTranslation } from "~/providers/I18nProvider";
|
|
||||||
import { useStorageTable } from "~/providers/StorageTableProvider";
|
import { useStorageTable } from "~/providers/StorageTableProvider";
|
||||||
import {
|
import type { FileMetadataWithAdmin } from "~/server/services/storage.service";
|
||||||
editFile,
|
|
||||||
type FileMetadataWithAdmin,
|
|
||||||
} from "~/server/services/storage.service";
|
|
||||||
|
|
||||||
import { api } from "~/utils/api";
|
import { api } from "~/utils/api";
|
||||||
|
|
||||||
export const StorageTable = ({
|
export const StorageTable = ({
|
||||||
|
|
@ -283,9 +278,24 @@ const RinominaDialog = ({
|
||||||
target: { allegatoId: string; filename: string | null } | null,
|
target: { allegatoId: string; filename: string | null } | null,
|
||||||
) => void;
|
) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation();
|
|
||||||
const utils = api.useUtils();
|
const utils = api.useUtils();
|
||||||
|
|
||||||
|
const { mutateAsync: renameFile } = api.storage.renameFile.useMutation({
|
||||||
|
onMutate: () => {
|
||||||
|
const toastId = toast.loading("Modifica in corso", {
|
||||||
|
icon: "🪛",
|
||||||
|
});
|
||||||
|
return { toastId };
|
||||||
|
},
|
||||||
|
onSuccess: async (_error, _variables, context) => {
|
||||||
|
await utils.storage.getAll.invalidate();
|
||||||
|
toast.success("File rinominato con successo", {
|
||||||
|
icon: "👍",
|
||||||
|
id: context?.toastId,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const handleEditSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
const handleEditSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const form = e.currentTarget;
|
const form = e.currentTarget;
|
||||||
|
|
@ -293,17 +303,10 @@ const RinominaDialog = ({
|
||||||
if (!formData.get("filename")) {
|
if (!formData.get("filename")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const rename = await editFile(
|
await renameFile({
|
||||||
renameTarget.allegatoId,
|
fileId: renameTarget.allegatoId,
|
||||||
formData.get("filename") as string,
|
name: formData.get("filename") as string,
|
||||||
);
|
});
|
||||||
if (rename.success) {
|
|
||||||
setRenameTarget(null);
|
|
||||||
toast.success("File rinominato con successo", { icon: "👍" });
|
|
||||||
await utils.storage.getAll.invalidate();
|
|
||||||
} else {
|
|
||||||
toast.error(rename.error);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
|
|
@ -312,8 +315,8 @@ const RinominaDialog = ({
|
||||||
>
|
>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>{t.modifica}</DialogTitle>
|
<DialogTitle>Rinomina</DialogTitle>
|
||||||
<DialogDescription className="sr-only">modifica</DialogDescription>
|
<DialogDescription className="sr-only">Rinomina</DialogDescription>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|
||||||
<form method="post" onSubmit={handleEditSubmit}>
|
<form method="post" onSubmit={handleEditSubmit}>
|
||||||
|
|
@ -323,10 +326,10 @@ const RinominaDialog = ({
|
||||||
defaultValue={renameTarget.filename || undefined}
|
defaultValue={renameTarget.filename || undefined}
|
||||||
minLength={5}
|
minLength={5}
|
||||||
name="filename"
|
name="filename"
|
||||||
placeholder="Modifica messaggio"
|
placeholder="Rinomina File"
|
||||||
type="text"
|
type="text"
|
||||||
/>
|
/>
|
||||||
<Button type="submit">{t.salva}</Button>
|
<Button type="submit">Salva</Button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ export const UploadComponent = ({
|
||||||
const [isUploading, setIsUploading] = useState(false);
|
const [isUploading, setIsUploading] = useState(false);
|
||||||
|
|
||||||
const { mutateAsync: setUserStorage } =
|
const { mutateAsync: setUserStorage } =
|
||||||
api.storage.addUserStorage.useMutation({
|
api.storage.addUserStorageEntry.useMutation({
|
||||||
onMutate: () => {
|
onMutate: () => {
|
||||||
toast(t.allegati.allegato_caricato, { icon: "📤" });
|
toast(t.allegati.allegato_caricato, { icon: "📤" });
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,13 @@ export async function uploadFile(
|
||||||
file: File,
|
file: File,
|
||||||
expiresAt: string | undefined,
|
expiresAt: string | undefined,
|
||||||
): Promise<UploadResponse> {
|
): Promise<UploadResponse> {
|
||||||
const formData = new FormData();
|
|
||||||
formData.append("file", file);
|
|
||||||
if (expiresAt) {
|
|
||||||
formData.append("expires_at", expiresAt);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("file", file);
|
||||||
|
if (expiresAt) {
|
||||||
|
formData.append("expires_at", expiresAt);
|
||||||
|
}
|
||||||
|
|
||||||
const response = await fetch(`/storage-api/upload`, {
|
const response = await fetch(`/storage-api/upload`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: formData,
|
body: formData,
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,20 @@
|
||||||
import { type NextRequest, NextResponse } from "next/server";
|
import { type NextRequest, NextResponse } from "next/server";
|
||||||
import { authMiddleware } from "~/middlewares/auth_middleware";
|
import { authMiddleware } from "~/middlewares/auth_middleware";
|
||||||
|
import { apisMiddleware } from "./middlewares/api_middleware";
|
||||||
|
|
||||||
export async function middleware(request: NextRequest) {
|
export async function middleware(request: NextRequest) {
|
||||||
//console.log("Middleware triggered for:", request.nextUrl.pathname);
|
//console.log("Middleware triggered for:", request.nextUrl.pathname);
|
||||||
|
const { pathname } = request.nextUrl;
|
||||||
|
if (pathname.startsWith("/storage-api/")) {
|
||||||
|
return await apisMiddleware(request);
|
||||||
|
}
|
||||||
|
|
||||||
return (await authMiddleware(request)) ?? NextResponse.next();
|
return (await authMiddleware(request)) ?? NextResponse.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
matcher: [
|
matcher: [
|
||||||
|
"/storage-api/:path*",
|
||||||
{
|
{
|
||||||
source: "/",
|
source: "/",
|
||||||
},
|
},
|
||||||
|
|
|
||||||
82
apps/infoalloggi/src/middlewares/api_middleware.ts
Normal file
82
apps/infoalloggi/src/middlewares/api_middleware.ts
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
import { type NextRequest, NextResponse } from "next/server";
|
||||||
|
import { env } from "~/env";
|
||||||
|
import { TOKEN_CONFIG } from "~/server/auth/configs";
|
||||||
|
import { verifyToken } from "~/server/auth/jwt";
|
||||||
|
|
||||||
|
export const apisMiddleware = async (req: NextRequest) => {
|
||||||
|
const { pathname, searchParams } = req.nextUrl;
|
||||||
|
console.log("APIs Middleware triggered for:", pathname);
|
||||||
|
const accessToken = req.cookies.get(
|
||||||
|
TOKEN_CONFIG.ACCESS_TOKEN_COOKIE_NAME,
|
||||||
|
)?.value;
|
||||||
|
if (!accessToken) {
|
||||||
|
return new NextResponse("Unauthorized", { status: 401 });
|
||||||
|
}
|
||||||
|
const payload = await verifyToken(accessToken);
|
||||||
|
if (!payload) {
|
||||||
|
return new NextResponse("Unauthorized", { status: 401 });
|
||||||
|
}
|
||||||
|
// Build the storage API URL correctly
|
||||||
|
const slug = pathname.replace("/storage-api/", "");
|
||||||
|
|
||||||
|
// Preserve existing query params and add token
|
||||||
|
const params = new URLSearchParams(searchParams);
|
||||||
|
params.set("token", env.STORAGE_TOKEN);
|
||||||
|
|
||||||
|
const storageUrl = `${env.STORAGE_URL}/${slug}?${params.toString()}`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Forward the request to storage API
|
||||||
|
const headers = new Headers(req.headers);
|
||||||
|
headers.delete("host");
|
||||||
|
headers.delete("cookie");
|
||||||
|
|
||||||
|
const response = await fetch(storageUrl, {
|
||||||
|
method: req.method,
|
||||||
|
headers: headers,
|
||||||
|
body:
|
||||||
|
req.method !== "GET" && req.method !== "HEAD" ? req.body : undefined,
|
||||||
|
// @ts-expect-error - duplex needed for request streaming
|
||||||
|
duplex: "half",
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
console.error("Storage API error:", response.status);
|
||||||
|
return new NextResponse("Storage API error", { status: response.status });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get response data
|
||||||
|
const data = await response.arrayBuffer();
|
||||||
|
|
||||||
|
// Create response with proper headers
|
||||||
|
const proxyResponse = new NextResponse(data, {
|
||||||
|
status: response.status,
|
||||||
|
statusText: response.statusText,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Copy relevant headers
|
||||||
|
const contentType = response.headers.get("Content-Type");
|
||||||
|
const contentDisposition = response.headers.get("Content-Disposition");
|
||||||
|
const contentLength = response.headers.get("Content-Length");
|
||||||
|
|
||||||
|
if (contentType) proxyResponse.headers.set("Content-Type", contentType);
|
||||||
|
if (contentDisposition)
|
||||||
|
proxyResponse.headers.set("Content-Disposition", contentDisposition);
|
||||||
|
if (contentLength)
|
||||||
|
proxyResponse.headers.set("Content-Length", contentLength);
|
||||||
|
|
||||||
|
// Set CORS headers
|
||||||
|
proxyResponse.headers.set("Access-Control-Allow-Origin", env.BASE_URL);
|
||||||
|
proxyResponse.headers.set("Access-Control-Allow-Credentials", "true");
|
||||||
|
proxyResponse.headers.delete("X-Frame-Options"); // Remove if set by storage API
|
||||||
|
proxyResponse.headers.set(
|
||||||
|
"Content-Security-Policy",
|
||||||
|
"frame-ancestors 'self'",
|
||||||
|
);
|
||||||
|
|
||||||
|
return proxyResponse;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Storage proxy error:", error);
|
||||||
|
return new NextResponse("Failed to proxy request", { status: 500 });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -206,7 +206,7 @@ const VisibComponent = ({
|
||||||
setOpen: (v: boolean) => void;
|
setOpen: (v: boolean) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const utils = api.useUtils();
|
const utils = api.useUtils();
|
||||||
const { data, isLoading } = api.storage.getStorageVisibility.useQuery({
|
const { data, isLoading } = api.storage.getStorageAccessDetails.useQuery({
|
||||||
storageIds,
|
storageIds,
|
||||||
});
|
});
|
||||||
const { data: users } = api.users.getUsers.useQuery();
|
const { data: users } = api.users.getUsers.useQuery();
|
||||||
|
|
@ -219,14 +219,14 @@ const VisibComponent = ({
|
||||||
return { toastId };
|
return { toastId };
|
||||||
},
|
},
|
||||||
onSuccess: async (_error, _variables, context) => {
|
onSuccess: async (_error, _variables, context) => {
|
||||||
await utils.storage.getStorageVisibility.invalidate();
|
await utils.storage.getStorageAccessDetails.invalidate();
|
||||||
toast.success("Utente rimosso", {
|
toast.success("Utente rimosso", {
|
||||||
icon: "🗑️",
|
icon: "🗑️",
|
||||||
id: context?.toastId,
|
id: context?.toastId,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const { mutate: add } = api.storage.addUserStorage.useMutation({
|
const { mutate: add } = api.storage.addUserStorageEntry.useMutation({
|
||||||
onMutate: () => {
|
onMutate: () => {
|
||||||
const toastId = toast.loading("Aggiunta utente in corso", {
|
const toastId = toast.loading("Aggiunta utente in corso", {
|
||||||
icon: "🪛",
|
icon: "🪛",
|
||||||
|
|
@ -234,7 +234,7 @@ const VisibComponent = ({
|
||||||
return { toastId };
|
return { toastId };
|
||||||
},
|
},
|
||||||
onSuccess: async (_error, _variables, context) => {
|
onSuccess: async (_error, _variables, context) => {
|
||||||
await utils.storage.getStorageVisibility.invalidate();
|
await utils.storage.getStorageAccessDetails.invalidate();
|
||||||
toast.success("Utente aggiunto", {
|
toast.success("Utente aggiunto", {
|
||||||
icon: "👍",
|
icon: "👍",
|
||||||
id: context?.toastId,
|
id: context?.toastId,
|
||||||
|
|
@ -250,7 +250,7 @@ const VisibComponent = ({
|
||||||
return { toastId };
|
return { toastId };
|
||||||
},
|
},
|
||||||
onSuccess: async (_error, _variables, context) => {
|
onSuccess: async (_error, _variables, context) => {
|
||||||
await utils.storage.getStorageVisibility.invalidate();
|
await utils.storage.getStorageAccessDetails.invalidate();
|
||||||
toast.success("Reset effettuato", {
|
toast.success("Reset effettuato", {
|
||||||
icon: "👍",
|
icon: "👍",
|
||||||
id: context?.toastId,
|
id: context?.toastId,
|
||||||
|
|
|
||||||
|
|
@ -60,10 +60,15 @@ export const storageRouter = createTRPCRouter({
|
||||||
.query(async ({ input }) => {
|
.query(async ({ input }) => {
|
||||||
return await retrieveUserFiles(input);
|
return await retrieveUserFiles(input);
|
||||||
}),
|
}),
|
||||||
|
getStorageAccessDetails: adminProcedure
|
||||||
//OLD
|
.input(z.object({ storageIds: z.string().array() }))
|
||||||
|
.query(async ({ input }) => {
|
||||||
addUserStorage: protectedProcedure
|
return await getMultipleWithRelations({
|
||||||
|
db,
|
||||||
|
ids: input.storageIds,
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
addUserStorageEntry: protectedProcedure
|
||||||
.input(z.custom<NewUsersStorage>())
|
.input(z.custom<NewUsersStorage>())
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
return await addUserStorage(input);
|
return await addUserStorage(input);
|
||||||
|
|
@ -73,15 +78,6 @@ export const storageRouter = createTRPCRouter({
|
||||||
return await getAllWithFromAdmin();
|
return await getAllWithFromAdmin();
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getStorageVisibility: adminProcedure
|
|
||||||
.input(z.object({ storageIds: z.string().array() }))
|
|
||||||
.query(async ({ input }) => {
|
|
||||||
return await getMultipleWithRelations({
|
|
||||||
db,
|
|
||||||
ids: input.storageIds,
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
|
|
||||||
renameFile: adminProcedure
|
renameFile: adminProcedure
|
||||||
.input(z.object({ fileId: z.string(), name: z.string() }))
|
.input(z.object({ fileId: z.string(), name: z.string() }))
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue