Skip to content

Commit

Permalink
Merge pull request #1785 from kleros/feat/restriction-roles
Browse files Browse the repository at this point in the history
feat(kleros-app): add-restrictions-check-in-upload-file
  • Loading branch information
alcercu authored Dec 19, 2024
2 parents f9cb5a6 + 5c43453 commit 4a84994
Show file tree
Hide file tree
Showing 7 changed files with 513 additions and 21 deletions.
3 changes: 3 additions & 0 deletions kleros-app/src/lib/atlas/hooks/useSessionStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ export function useSessionStorage<T>(keyName: string, defaultValue: T) {

return value ? JSON.parse(value) : defaultValue;
} catch (err) {
// eslint-disable-next-line no-console
console.log("useSessionStorage:", { err });

return defaultValue;
}
});
Expand Down
35 changes: 33 additions & 2 deletions kleros-app/src/lib/atlas/providers/AtlasProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
import { GraphQLError } from "graphql";
import { isUndefined } from "../../../utils";
import { useSessionStorage } from "../hooks/useSessionStorage";
import { fetchRestrictions, Role } from "../utils/fetchRestrictions";

interface IAtlasProvider {
isVerified: boolean;
Expand All @@ -44,6 +45,7 @@ interface IAtlasProvider {
isError: boolean;
}
>;
roleRestrictions: Role[] | undefined;
}

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

/**
* @description verifies user authorisation
Expand Down Expand Up @@ -142,6 +144,22 @@ export const AtlasProvider: React.FC<{ config: AtlasConfig; children?: React.Rea
queryClient
);

const { data: roleRestrictions } = useQuery(
{
queryKey: [`RoleRestrictions`],
enabled: Boolean(config.product),
staleTime: Infinity,
queryFn: async () => {
try {
return await fetchRestrictions(atlasGqlClient, config.product);
} catch {
return undefined;
}
},
},
queryClient
);

useEffect(() => {
if (!isVerified) return;
refetchUser();
Expand Down Expand Up @@ -255,6 +273,17 @@ export const AtlasProvider: React.FC<{ config: AtlasConfig; children?: React.Rea
async (file: File, role: Roles) => {
try {
if (!address || !isVerified || !config.uri || !authToken) return null;

if (roleRestrictions) {
const restrictions = roleRestrictions.find((supportedRoles) => Roles[supportedRoles.name] === role);

if (!restrictions) throw new Error("Unsupported role.");
if (!restrictions.restriction.allowedMimeTypes.includes(file.type)) throw new Error("Unsupported file type.");
if (file.size > restrictions.restriction.maxSize)
throw new Error(
`File too big. Max allowed size : ${(restrictions.restriction.maxSize / (1024 * 1024)).toFixed(2)} mb.`
);
}
setIsUploadingFile(true);

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

/**
Expand Down Expand Up @@ -309,6 +338,7 @@ export const AtlasProvider: React.FC<{ config: AtlasConfig; children?: React.Rea
isUploadingFile,
uploadFile,
confirmEmail,
roleRestrictions,
}),
[
isVerified,
Expand All @@ -324,6 +354,7 @@ export const AtlasProvider: React.FC<{ config: AtlasConfig; children?: React.Rea
isUploadingFile,
uploadFile,
confirmEmail,
roleRestrictions,
]
)}
>
Expand Down
40 changes: 40 additions & 0 deletions kleros-app/src/lib/atlas/utils/fetchRestrictions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { gql, type GraphQLClient } from "graphql-request";
import { Products } from ".";

export type Role = {
name: string;
restriction: {
maxSize: number;
allowedMimeTypes: string[];
};
};

type FetchRolesResponse = {
roles: Role[];
};

const query = gql`
query Roles($product: Products!) {
roles(product: $product) {
name
restriction {
maxSize
allowedMimeTypes
}
}
}
`;

export async function fetchRestrictions(client: GraphQLClient, product: Products): Promise<Role[]> {
return client
.request<FetchRolesResponse>(query, { product })
.then((response) => response.roles)
.catch((errors) => {
// eslint-disable-next-line no-console
console.log("Error fetching roles :", { errors });
const errorMessage = Array.isArray(errors?.response?.errors)
? errors.response.errors[0]?.message
: "Error fetching roles";
throw Error(errorMessage);
});
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
"web-devtools",
"eslint-config",
"prettier-config",
"tsconfig"
"tsconfig",
"kleros-app"
],
"packageManager": "[email protected]",
"volta": {
Expand Down
4 changes: 2 additions & 2 deletions web/src/pages/Home/CourtOverview/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React from "react";
import styled from "styled-components";

import { responsiveSize } from "styles/responsiveSize";

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

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

import { responsiveSize } from "styles/responsiveSize";

import { InternalLink } from "components/InternalLink";

const StyledHeader = styled.div`
Expand Down
Loading

0 comments on commit 4a84994

Please sign in to comment.