Skip to content

Commit 87eacc1

Browse files
committedDec 12, 2024··
feat(kleros-app): add-restrictions-check-in-upload-file
1 parent e8e48f4 commit 87eacc1

File tree

6 files changed

+526
-18
lines changed

6 files changed

+526
-18
lines changed
 

‎kleros-app/src/lib/atlas/hooks/useSessionStorage.ts

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ export function useSessionStorage<T>(keyName: string, defaultValue: T) {
77

88
return value ? JSON.parse(value) : defaultValue;
99
} catch (err) {
10+
// eslint-disable-next-line no-console
11+
console.log("useSessionStorage:", { err });
12+
1013
return defaultValue;
1114
}
1215
});

‎kleros-app/src/lib/atlas/providers/AtlasProvider.tsx

+33-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
import { GraphQLError } from "graphql";
2626
import { isUndefined } from "../../../utils";
2727
import { useSessionStorage } from "../hooks/useSessionStorage";
28+
import { fetchRestrictions, Role } from "../utils/fetchRestrictions";
2829

2930
interface IAtlasProvider {
3031
isVerified: boolean;
@@ -44,6 +45,7 @@ interface IAtlasProvider {
4445
isError: boolean;
4546
}
4647
>;
48+
roleRestrictions: Role[] | undefined;
4749
}
4850

4951
const Context = createContext<IAtlasProvider | undefined>(undefined);
@@ -73,7 +75,7 @@ export const AtlasProvider: React.FC<{ config: AtlasConfig; children?: React.Rea
7375
}
7476
: undefined;
7577
return new GraphQLClient(`${config.uri}/graphql`, { headers });
76-
}, [authToken]);
78+
}, [authToken, config.uri]);
7779

7880
/**
7981
* @description verifies user authorisation
@@ -142,6 +144,22 @@ export const AtlasProvider: React.FC<{ config: AtlasConfig; children?: React.Rea
142144
queryClient
143145
);
144146

147+
const { data: roleRestrictions } = useQuery(
148+
{
149+
queryKey: [`RoleRestrictions`],
150+
enabled: Boolean(config.product),
151+
staleTime: Infinity,
152+
queryFn: async () => {
153+
try {
154+
return await fetchRestrictions(atlasGqlClient, config.product);
155+
} catch {
156+
return undefined;
157+
}
158+
},
159+
},
160+
queryClient
161+
);
162+
145163
useEffect(() => {
146164
if (!isVerified) return;
147165
refetchUser();
@@ -255,6 +273,17 @@ export const AtlasProvider: React.FC<{ config: AtlasConfig; children?: React.Rea
255273
async (file: File, role: Roles) => {
256274
try {
257275
if (!address || !isVerified || !config.uri || !authToken) return null;
276+
277+
if (roleRestrictions) {
278+
const restrictions = roleRestrictions.find((supportedRoles) => Roles[supportedRoles.name] === role);
279+
280+
if (!restrictions) throw new Error("Unsupported role.");
281+
if (!restrictions.restriction.allowedMimeTypes.includes(file.type)) throw new Error("Unsupported file type.");
282+
if (file.size > restrictions.restriction.maxSize)
283+
throw new Error(
284+
`File too big. Max allowed size : ${((restrictions.restriction.maxSize / 1024) * 1024).toFixed(2)} mb.`
285+
);
286+
}
258287
setIsUploadingFile(true);
259288

260289
const hash = await fetchWithAuthErrorHandling(() =>
@@ -267,7 +296,7 @@ export const AtlasProvider: React.FC<{ config: AtlasConfig; children?: React.Rea
267296
setIsUploadingFile(false);
268297
}
269298
},
270-
[address, isVerified, setIsUploadingFile, authToken, config.uri, config.product]
299+
[address, isVerified, setIsUploadingFile, authToken, config.uri, config.product, roleRestrictions]
271300
);
272301

273302
/**
@@ -309,6 +338,7 @@ export const AtlasProvider: React.FC<{ config: AtlasConfig; children?: React.Rea
309338
isUploadingFile,
310339
uploadFile,
311340
confirmEmail,
341+
roleRestrictions,
312342
}),
313343
[
314344
isVerified,
@@ -324,6 +354,7 @@ export const AtlasProvider: React.FC<{ config: AtlasConfig; children?: React.Rea
324354
isUploadingFile,
325355
uploadFile,
326356
confirmEmail,
357+
roleRestrictions,
327358
]
328359
)}
329360
>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { gql, type GraphQLClient } from "graphql-request";
2+
import { Products } from ".";
3+
4+
export type Role = {
5+
name: string;
6+
restriction: {
7+
maxSize: number;
8+
allowedMimeTypes: string[];
9+
};
10+
};
11+
12+
type FetchRolesResponse = {
13+
roles: Role[];
14+
};
15+
16+
const query = gql`
17+
query Roles($product: Products!) {
18+
roles(product: $product) {
19+
name
20+
restriction {
21+
maxSize
22+
allowedMimeTypes
23+
}
24+
}
25+
}
26+
`;
27+
28+
export async function fetchRestrictions(client: GraphQLClient, product: Products): Promise<Role[]> {
29+
return client
30+
.request<FetchRolesResponse>(query, { product })
31+
.then((response) => response.roles)
32+
.catch((errors) => {
33+
// eslint-disable-next-line no-console
34+
console.log("Error fetching roles :", { errors });
35+
const errorMessage = Array.isArray(errors?.response?.errors)
36+
? errors.response.errors[0]?.message
37+
: "Error fetching roles";
38+
throw Error(errorMessage);
39+
});
40+
}

‎package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
"web-devtools",
2626
"eslint-config",
2727
"prettier-config",
28-
"tsconfig"
28+
"tsconfig",
29+
"kleros-app"
2930
],
3031
"packageManager": "yarn@4.5.1",
3132
"volta": {

‎web/src/pages/Home/CourtOverview/Header.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import React from "react";
22
import styled from "styled-components";
33

4-
import { responsiveSize } from "styles/responsiveSize";
5-
64
import { Link } from "react-router-dom";
75

86
import { Button } from "@kleros/ui-components-library";
97

108
import Bookmark from "svgs/icons/bookmark.svg";
119

10+
import { responsiveSize } from "styles/responsiveSize";
11+
1212
const StyledHeader = styled.div`
1313
display: flex;
1414
flex-wrap: wrap;

‎yarn.lock

+446-13
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.