Revize 8c45ccb0
Přidáno uživatelem hrubyjar před téměř 3 roky(ů)
Backend/Backend/Controllers/AuthController.cs | ||
---|---|---|
24 | 24 |
[HttpPost("/auth/login")] |
25 | 25 |
[ProducesResponseType((int) HttpStatusCode.OK, Type = typeof(LoginResponse))] |
26 | 26 |
[ProducesResponseType((int) HttpStatusCode.Forbidden)] |
27 |
public ActionResult<LoginResponse> Login([FromBody] LoginRequest loginData)
|
|
27 |
public ActionResult<LoginResponse> Index([FromBody] LoginRequest loginData)
|
|
28 | 28 |
{ |
29 | 29 |
try |
30 | 30 |
{ |
31 |
var loginResponse = authService.Login(loginData.Username, loginData.Password);
|
|
31 |
var loginResponse = authService.Index(loginData.Username, loginData.Password);
|
|
32 | 32 |
if (loginResponse == null) |
33 | 33 |
{ |
34 | 34 |
return Forbid(); |
Backend/Core/Services/AuthService/AuthService.cs | ||
---|---|---|
15 | 15 |
this.jwtUtils = jwtUtils; |
16 | 16 |
} |
17 | 17 |
|
18 |
public LoginResponse? Login(string username, string password)
|
|
18 |
public LoginResponse? Index(string username, string password)
|
|
19 | 19 |
{ |
20 | 20 |
var user = userService.CheckUsernamePassword(username, password); |
21 | 21 |
|
Backend/Core/Services/AuthService/IAuthService.cs | ||
---|---|---|
5 | 5 |
|
6 | 6 |
public interface IAuthService |
7 | 7 |
{ |
8 |
public LoginResponse? Login(string username, string password);
|
|
8 |
public LoginResponse? Index(string username, string password);
|
|
9 | 9 |
} |
webapp/components/common/Auth.tsx | ||
---|---|---|
1 |
import React, { ReactNode, useContext, useEffect, useState } from 'react'; |
|
2 |
import { useRouter } from 'next/router'; |
|
3 |
import { LoggedUserContext } from '../../contexts/LoggedUserContext'; |
|
4 |
import { ERole } from '../../api'; |
|
5 |
|
|
6 |
export default function Auth({ |
|
7 |
minRole, |
|
8 |
children, |
|
9 |
}: { |
|
10 |
minRole?: ERole | null; |
|
11 |
children: ReactNode; |
|
12 |
}) { |
|
13 |
const { role, tokenExpiration, logout } = useContext(LoggedUserContext); |
|
14 |
const [clientRender, setClientRender] = useState(false); |
|
15 |
const router = useRouter(); |
|
16 |
|
|
17 |
function checkRole(): boolean { |
|
18 |
if (!minRole) { |
|
19 |
// no role required |
|
20 |
return true; |
|
21 |
} |
|
22 |
|
|
23 |
return role === minRole ?? false; |
|
24 |
} |
|
25 |
|
|
26 |
useEffect(() => { |
|
27 |
setClientRender(true); |
|
28 |
}, []); |
|
29 |
|
|
30 |
if (tokenExpiration?.isBefore(new Date())) { |
|
31 |
// token has expired |
|
32 |
|
|
33 |
(async () => { |
|
34 |
await logout(); |
|
35 |
await router.push('/'); |
|
36 |
})(); |
|
37 |
} |
|
38 |
|
|
39 |
if (clientRender && checkRole()) { |
|
40 |
return <>{children}</>; |
|
41 |
} |
|
42 |
|
|
43 |
return null; |
|
44 |
} |
webapp/components/navigation/AdminNavBar.tsx | ||
---|---|---|
1 |
/** |
|
2 |
* Creates a navigation bar of an admin. |
|
3 |
* @returns Navigation bar of an admin. |
|
4 |
*/ |
|
5 |
export function AdminNavBar() { |
|
1 |
import React, { useCallback, useContext } from 'react'; |
|
2 |
import { Menu } from 'antd'; |
|
3 |
import { useRouter } from 'next/router'; |
|
4 |
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; |
|
5 |
import { LoggedUserContext } from '../../contexts/LoggedUserContext'; |
|
6 |
import { |
|
7 |
faUser, |
|
8 |
faFileExport, |
|
9 |
faFileLines, |
|
10 |
faUsers, |
|
11 |
faTags, |
|
12 |
faBookmark, |
|
13 |
} from '@fortawesome/free-solid-svg-icons'; |
|
14 |
|
|
15 |
const UserNavBar = () => { |
|
16 |
const router = useRouter(); |
|
17 |
const { logout } = useContext(LoggedUserContext); |
|
18 |
const { SubMenu } = Menu; |
|
19 |
|
|
20 |
const handleLogout = useCallback(() => { |
|
21 |
logout(); |
|
22 |
router.push('/login'); |
|
23 |
}, [logout, router]); |
|
24 |
|
|
6 | 25 |
return ( |
7 |
<div> |
|
8 |
<p>Navigation bar of an admin.</p> |
|
9 |
</div> |
|
26 |
<Menu theme="dark" mode="horizontal"> |
|
27 |
<Menu.Item style={{}} key="1" onClick={() => router.push('/documents/admin')}> |
|
28 |
<FontAwesomeIcon icon={faFileLines} /> Dokumenty |
|
29 |
</Menu.Item> |
|
30 |
<Menu.Item style={{}} key="2" onClick={() => router.push('/users')}> |
|
31 |
<FontAwesomeIcon icon={faUsers} /> Uživatelé |
|
32 |
</Menu.Item> |
|
33 |
<Menu.Item style={{}} key="3" onClick={() => router.push('/tags')}> |
|
34 |
<FontAwesomeIcon icon={faTags} /> Značky |
|
35 |
</Menu.Item> |
|
36 |
<Menu.Item style={{}} key="4" onClick={() => router.push('/classes')}> |
|
37 |
<FontAwesomeIcon icon={faBookmark} /> Třídy |
|
38 |
</Menu.Item> |
|
39 |
<Menu.Item style={{}} key="5" onClick={() => router.push('/export')}> |
|
40 |
<FontAwesomeIcon icon={faFileExport} /> Export |
|
41 |
</Menu.Item> |
|
42 |
|
|
43 |
<SubMenu |
|
44 |
icon={<FontAwesomeIcon icon={faUser} />} |
|
45 |
key="account" |
|
46 |
title={'Admin XY'} // TODO show username |
|
47 |
> |
|
48 |
<Menu.Item key="setting:2" onClick={() => handleLogout()}> |
|
49 |
Odhlásit se |
|
50 |
</Menu.Item> |
|
51 |
</SubMenu> |
|
52 |
</Menu> |
|
10 | 53 |
); |
11 |
} |
|
54 |
}; |
|
55 |
|
|
56 |
export default UserNavBar; |
webapp/components/navigation/UserNavBar.tsx | ||
---|---|---|
1 |
/** |
|
2 |
* Creates a navigation bar of a normal user (annotator). |
|
3 |
* @returns Navigation bar of a user. |
|
4 |
*/ |
|
5 |
export function UserNavBar() { |
|
1 |
import React, { useCallback, useContext } from 'react'; |
|
2 |
import { Menu } from 'antd'; |
|
3 |
import { useRouter } from 'next/router'; |
|
4 |
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; |
|
5 |
import { faFileLines, faUser } from '@fortawesome/free-solid-svg-icons'; |
|
6 |
import { LoggedUserContext } from '../../contexts/LoggedUserContext'; |
|
7 |
|
|
8 |
const UserNavBar = () => { |
|
9 |
const router = useRouter(); |
|
10 |
const { logout } = useContext(LoggedUserContext); |
|
11 |
const { SubMenu } = Menu; |
|
12 |
|
|
13 |
const handleLogout = useCallback(() => { |
|
14 |
logout(); |
|
15 |
router.push('/login'); |
|
16 |
}, [logout, router]); |
|
17 |
|
|
6 | 18 |
return ( |
7 |
<div> |
|
8 |
<p>Navigation bar of a normal user.</p> |
|
9 |
</div> |
|
19 |
<Menu theme="dark" mode="horizontal"> |
|
20 |
<Menu.Item key="1" onClick={() => router.push('/documents/annotator')}> |
|
21 |
<FontAwesomeIcon icon={faFileLines} /> Dokumenty |
|
22 |
</Menu.Item> |
|
23 |
|
|
24 |
<SubMenu |
|
25 |
key="account" |
|
26 |
icon={<FontAwesomeIcon icon={faUser} />} |
|
27 |
title={'Anotátor XY'} // TODO show username |
|
28 |
> |
|
29 |
<Menu.Item key="setting:2" onClick={() => handleLogout()}> |
|
30 |
Odhlásit se |
|
31 |
</Menu.Item> |
|
32 |
</SubMenu> |
|
33 |
</Menu> |
|
10 | 34 |
); |
11 |
} |
|
35 |
}; |
|
36 |
|
|
37 |
export default UserNavBar; |
webapp/components/types/auth.ts | ||
---|---|---|
1 |
import { AppProps } from 'next/app'; |
|
2 |
import { ERole } from '../../api'; |
|
3 |
|
|
4 |
export type SecuredComponent = AppProps['Component'] & { |
|
5 |
auth: ComponentAuth; |
|
6 |
}; |
|
7 |
|
|
8 |
export class ComponentAuth { |
|
9 |
minRole: ERole | null; |
|
10 |
|
|
11 |
constructor(minRole: ERole | null = null) { |
|
12 |
this.minRole = minRole; |
|
13 |
} |
|
14 |
} |
webapp/contexts/LoggedUserContext.tsx | ||
---|---|---|
1 |
import React, { createContext, useEffect, useState } from 'react'; |
|
2 |
import moment, { Moment } from 'moment'; |
|
3 |
import { getTokenData, loginUser, logoutUser } from '../utils/login'; |
|
4 |
import { useRouter } from 'next/router'; |
|
5 |
import { ERole } from '../api'; |
|
6 |
|
|
7 |
interface ILoggedUserProvider { |
|
8 |
login: (email: string, password: string) => Promise<boolean>; |
|
9 |
logout: () => Promise<boolean>; |
|
10 |
|
|
11 |
tokenExpiration?: Moment | null; |
|
12 |
setTokenExpiration?: (newTokenExpiration: Moment | null) => void; |
|
13 |
|
|
14 |
role?: ERole | undefined; |
|
15 |
setRole?: (newRoles: ERole | undefined) => void; |
|
16 |
|
|
17 |
refreshData?: () => Promise<void>; |
|
18 |
} |
|
19 |
|
|
20 |
export const LoggedUserContext = createContext<ILoggedUserProvider>({ |
|
21 |
login: async (username: string, password: string): Promise<boolean> => { |
|
22 |
return false; |
|
23 |
}, |
|
24 |
logout: async (): Promise<boolean> => { |
|
25 |
return false; |
|
26 |
}, |
|
27 |
}); |
|
28 |
|
|
29 |
const LoggedUserProvider = (props: { children: any }) => { |
|
30 |
const [role, setRole] = useState<ERole>(); |
|
31 |
const [tokenExpiration, setTokenExpiration] = useState<Moment | null>(null); |
|
32 |
const router = useRouter(); |
|
33 |
|
|
34 |
useEffect(() => { |
|
35 |
loadData(); |
|
36 |
}, []); |
|
37 |
|
|
38 |
async function loadData() { |
|
39 |
const tokenData = await getTokenData(); |
|
40 |
if (!tokenData) { |
|
41 |
setRole(undefined); |
|
42 |
setTokenExpiration(null); |
|
43 |
} else { |
|
44 |
setRole(tokenData.role); |
|
45 |
setTokenExpiration(moment(tokenData.expiration)); |
|
46 |
} |
|
47 |
} |
|
48 |
|
|
49 |
async function login(username: string, password: string): Promise<boolean> { |
|
50 |
const res = await loginUser(username, password); |
|
51 |
if (!res) { |
|
52 |
return false; |
|
53 |
} |
|
54 |
|
|
55 |
await loadData(); |
|
56 |
|
|
57 |
return true; |
|
58 |
} |
|
59 |
|
|
60 |
async function logout(): Promise<boolean> { |
|
61 |
const res = await logoutUser(); |
|
62 |
|
|
63 |
if (res) { |
|
64 |
setRole(undefined); |
|
65 |
} |
|
66 |
await router.push('/'); |
|
67 |
return res; |
|
68 |
} |
|
69 |
|
|
70 |
return ( |
|
71 |
<LoggedUserContext.Provider |
|
72 |
value={{ |
|
73 |
tokenExpiration, |
|
74 |
setTokenExpiration, |
|
75 |
role, |
|
76 |
setRole, |
|
77 |
refreshData: loadData, |
|
78 |
login, |
|
79 |
logout, |
|
80 |
}} |
|
81 |
> |
|
82 |
{props.children} |
|
83 |
</LoggedUserContext.Provider> |
|
84 |
); |
|
85 |
}; |
|
86 |
|
|
87 |
export default LoggedUserProvider; |
webapp/controllers.ts | ||
---|---|---|
1 |
import { UserApi, AuthApi, DocumentApi, AnnotationApi, TagApi } from './api'; |
|
2 |
import { axios } from './utils/axios'; |
|
3 |
import { Configuration } from './api'; |
|
4 |
import { getToken } from './utils/login'; |
|
5 |
|
|
6 |
let baseURL = 'https://localhost:7241'; |
|
7 |
|
|
8 |
const defaultConfig: Configuration = new Configuration({ |
|
9 |
basePath: baseURL, |
|
10 |
accessToken: getToken, |
|
11 |
}); |
|
12 |
|
|
13 |
export const authController = new AuthApi(defaultConfig, baseURL, axios); |
|
14 |
export const userController = new UserApi(defaultConfig, baseURL, axios); |
|
15 |
export const documentController = new DocumentApi(defaultConfig, baseURL, axios); |
|
16 |
export const annotationController = new AnnotationApi(defaultConfig, baseURL, axios); |
|
17 |
export const tagController = new TagApi(defaultConfig, baseURL, axios); |
webapp/generate-api.sh | ||
---|---|---|
1 |
#!/bin/bash |
|
2 |
rm -rf api |
|
3 |
npx @openapitools/openapi-generator-cli generate \ |
|
4 |
-i http://localhost:5241/swagger/v1/swagger.json \ |
|
5 |
-g typescript-axios \ |
|
6 |
-o api |
webapp/hooks/index.tsx | ||
---|---|---|
1 |
import useUnauthRedirect from './useUnauthRedirect'; |
|
2 |
|
|
3 |
export { useUnauthRedirect }; |
webapp/hooks/useUnauthRedirect.tsx | ||
---|---|---|
1 |
import { useRouter } from 'next/router'; |
|
2 |
import { useEffect } from 'react'; |
|
3 |
import { getToken } from '../utils/login'; |
|
4 |
|
|
5 |
/** |
|
6 |
* Performs redirect when user is unauthenticated. |
|
7 |
* @param path path where to redirect |
|
8 |
* @returns redirecting? |
|
9 |
*/ |
|
10 |
const useUnauthRedirect = (path: string): boolean => { |
|
11 |
const router = useRouter(); |
|
12 |
let tokenEmpty = false; |
|
13 |
useEffect(() => { |
|
14 |
async function checkToken() { |
|
15 |
const empty = (await getToken()) === ''; |
|
16 |
if (tokenEmpty) { |
|
17 |
router.push(path); |
|
18 |
} |
|
19 |
// eslint-disable-next-line react-hooks/exhaustive-deps |
|
20 |
tokenEmpty = empty; |
|
21 |
} |
|
22 |
checkToken(); |
|
23 |
}, [path, router]); |
|
24 |
|
|
25 |
return tokenEmpty; |
|
26 |
}; |
|
27 |
|
|
28 |
export default useUnauthRedirect; |
webapp/layouts/MainLayout.tsx | ||
---|---|---|
1 |
import { UserNavBar } from '../components/navigation/UserNavBar'; |
|
2 |
import { AdminNavBar } from '../components/navigation/AdminNavBar'; |
|
3 | 1 |
import 'antd/dist/antd.css'; |
4 | 2 |
import styles from '/styles/MainLayout.module.scss'; |
5 |
import React from 'react'; |
|
3 |
import { useContext } from 'react'; |
|
4 |
import { LoggedUserContext } from '../contexts/LoggedUserContext'; |
|
5 |
import AdminNavBar from '../components/navigation/AdminNavBar'; |
|
6 |
import UserNavBar from '../components/navigation/UserNavBar'; |
|
6 | 7 |
|
7 | 8 |
/** |
8 | 9 |
* Creates layout of main screens. |
... | ... | |
10 | 11 |
* @returns The login screen. |
11 | 12 |
*/ |
12 | 13 |
export function MainLayout(props: { children: React.ReactNode }) { |
14 |
const { role } = useContext(LoggedUserContext); |
|
15 |
const isAdmin = role === 'ADMINISTRATOR'; |
|
16 |
const isAnnotator = role === 'ANNOTATOR'; |
|
17 |
|
|
13 | 18 |
return ( |
14 | 19 |
<div className={styles.layoutWrapper}> |
15 | 20 |
<div className={styles.header}> |
16 |
{/** |
|
17 |
@todo: Select correct navigation bar |
|
18 |
{user && <UserNavBar />} |
|
19 |
{admin && <AdminNavBar />} |
|
20 |
**/} |
|
21 |
{(isAdmin && <AdminNavBar />) || (isAnnotator && <UserNavBar />)} |
|
21 | 22 |
</div> |
22 | 23 |
<main className={styles.content}>{props.children}</main> |
23 |
<div className={styles.footer}></div>
|
|
24 |
<div className={styles.footer} />
|
|
24 | 25 |
</div> |
25 | 26 |
); |
26 | 27 |
} |
webapp/package.json | ||
---|---|---|
6 | 6 |
"dev": "next dev", |
7 | 7 |
"build": "next build", |
8 | 8 |
"start": "next start", |
9 |
"lint": "next lint" |
|
9 |
"lint": "next lint", |
|
10 |
"generate-api": "openapi-generator-cli generate -i http://localhost:5241/swagger/v1/swagger.json -g typescript-axios -o api", |
|
11 |
"postinstall": "yarn generate-api", |
|
12 |
"deduplicate": "yarn-deduplicate yarn.lock" |
|
10 | 13 |
}, |
11 | 14 |
"dependencies": { |
12 |
"@fortawesome/fontawesome-free": "^6.1.0", |
|
15 |
"@fortawesome/fontawesome-svg-core": "^6.1.1", |
|
16 |
"@fortawesome/free-solid-svg-icons": "^6.1.1", |
|
17 |
"@fortawesome/react-fontawesome": "^0.1.18", |
|
13 | 18 |
"antd": "^4.19.5", |
14 | 19 |
"axios": "^0.26.1", |
15 | 20 |
"bootstrap": "^5.1.3", |
... | ... | |
17 | 22 |
"next": "12.1.0", |
18 | 23 |
"react": "17.0.2", |
19 | 24 |
"react-bootstrap": "^2.2.1", |
20 |
"react-dom": "17.0.2" |
|
25 |
"react-dom": "17.0.2", |
|
26 |
"sweetalert2": "^11.4.8", |
|
27 |
"sweetalert2-react-content": "^4.2.0" |
|
21 | 28 |
}, |
22 | 29 |
"devDependencies": { |
30 |
"@openapitools/openapi-generator-cli": "2.4.26", |
|
23 | 31 |
"@types/node": "17.0.21", |
24 | 32 |
"@types/react": "17.0.41", |
25 | 33 |
"eslint": "8.11.0", |
webapp/pages/_app.tsx | ||
---|---|---|
1 |
import '../styles/globals.css' |
|
2 |
import type {AppProps} from 'next/app' |
|
1 |
// @ts-nocheck |
|
2 |
import '../styles/globals.css'; |
|
3 |
import 'bootstrap/dist/css/bootstrap.css'; |
|
3 | 4 |
|
4 |
import 'bootstrap/dist/css/bootstrap.css' |
|
5 |
import type { AppProps } from 'next/app'; |
|
6 |
import Head from 'next/head'; |
|
7 |
import { SecuredComponent } from '../components/types/auth'; |
|
8 |
import LoggedUserProvider from '../contexts/LoggedUserContext'; |
|
9 |
import Auth from '../components/common/Auth'; |
|
5 | 10 |
|
6 |
function MyApp({Component, pageProps}: AppProps) { |
|
7 |
return <Component {...pageProps} /> |
|
11 |
function MyApp({ |
|
12 |
Component, |
|
13 |
pageProps, |
|
14 |
}: { |
|
15 |
Component: SecuredComponent; |
|
16 |
pageProps: AppProps['pageProps']; |
|
17 |
}) { |
|
18 |
return ( |
|
19 |
<LoggedUserProvider> |
|
20 |
<Head> |
|
21 |
<link rel="shortcut icon" href={'/favicon.ico'} /> |
|
22 |
<title>Annotation Tool</title> |
|
23 |
</Head> |
|
24 |
{Component.auth ? ( |
|
25 |
<Auth minRole={Component.auth?.minRole}> |
|
26 |
<Component {...pageProps} /> |
|
27 |
</Auth> |
|
28 |
) : ( |
|
29 |
<Component {...pageProps} /> |
|
30 |
)} |
|
31 |
</LoggedUserProvider> |
|
32 |
); |
|
8 | 33 |
} |
9 | 34 |
|
10 |
export default MyApp |
|
35 |
export default MyApp; |
webapp/pages/classes/index.tsx | ||
---|---|---|
1 |
import 'antd/dist/antd.css'; |
|
2 |
import React, { useContext, useEffect } from 'react'; |
|
3 |
|
|
4 |
import { useUnauthRedirect } from '../../hooks'; |
|
5 |
import { useRouter } from 'next/router'; |
|
6 |
import { Typography } from 'antd'; |
|
7 |
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; |
|
8 |
import { faBookmark } from '@fortawesome/free-solid-svg-icons'; |
|
9 |
import { LoggedUserContext } from '../../contexts/LoggedUserContext'; |
|
10 |
import { MainLayout } from '../../layouts/mainLayout'; |
|
11 |
|
|
12 |
function ClassesPage() { |
|
13 |
const redirecting = useUnauthRedirect('/login'); |
|
14 |
const { logout, role } = useContext(LoggedUserContext); |
|
15 |
const router = useRouter(); |
|
16 |
|
|
17 |
useEffect(() => { |
|
18 |
if (role !== 'ADMINISTRATOR') { |
|
19 |
logout(); |
|
20 |
router.push('/login'); |
|
21 |
} |
|
22 |
|
|
23 |
if (!redirecting) { |
|
24 |
// TODO load classes |
|
25 |
} |
|
26 |
}, [redirecting, role, router]); |
|
27 |
|
|
28 |
return redirecting || role !== 'ADMINISTRATOR' ? null : ( |
|
29 |
<MainLayout> |
|
30 |
<Typography.Title level={2}> |
|
31 |
<FontAwesomeIcon icon={faBookmark} /> Třídy |
|
32 |
</Typography.Title> |
|
33 |
</MainLayout> |
|
34 |
); |
|
35 |
} |
|
36 |
|
|
37 |
export default ClassesPage; |
webapp/pages/documents/admin/index.tsx | ||
---|---|---|
1 |
import 'antd/dist/antd.css'; |
|
2 |
import React, { useContext, useEffect } from 'react'; |
|
3 |
|
|
4 |
import { useUnauthRedirect } from '../../../hooks'; |
|
5 |
import { useRouter } from 'next/router'; |
|
6 |
import { Button, Typography } from 'antd'; |
|
7 |
import { faFileLines } from '@fortawesome/free-solid-svg-icons'; |
|
8 |
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; |
|
9 |
import { LoggedUserContext } from '../../../contexts/LoggedUserContext'; |
|
10 |
import { MainLayout } from '../../../layouts/mainLayout'; |
|
11 |
import { documentController } from '../../../controllers'; |
|
12 |
|
|
13 |
function AdminDocumentPage() { |
|
14 |
const redirecting = useUnauthRedirect('/login'); |
|
15 |
const { logout, role } = useContext(LoggedUserContext); |
|
16 |
const router = useRouter(); |
|
17 |
useEffect(() => { |
|
18 |
if (role !== 'ADMINISTRATOR') { |
|
19 |
logout(); |
|
20 |
router.push('/login'); |
|
21 |
} |
|
22 |
|
|
23 |
if (!redirecting) { |
|
24 |
// TODO load documents |
|
25 |
} |
|
26 |
}, [logout, redirecting, role, router]); |
|
27 |
|
|
28 |
const showModal = () => { |
|
29 |
// TODO show AddDocument component |
|
30 |
}; |
|
31 |
|
|
32 |
return redirecting || role !== 'ADMINISTRATOR' ? null : ( |
|
33 |
<MainLayout> |
|
34 |
<Typography.Title level={2}> |
|
35 |
<FontAwesomeIcon icon={faFileLines} /> Dokumenty |
|
36 |
</Typography.Title> |
|
37 |
<Button type={'primary'} onClick={showModal}> |
|
38 |
Nahrát dokument |
|
39 |
</Button> |
|
40 |
</MainLayout> |
|
41 |
); |
|
42 |
} |
|
43 |
|
|
44 |
export default AdminDocumentPage; |
webapp/pages/documents/annotator/index.tsx | ||
---|---|---|
1 |
import 'antd/dist/antd.css'; |
|
2 |
import React, { useContext, useEffect } from 'react'; |
|
3 |
|
|
4 |
import { useUnauthRedirect } from '../../../hooks'; |
|
5 |
import { useRouter } from 'next/router'; |
|
6 |
import { Layout, Typography } from 'antd'; |
|
7 |
import UserNavBar from '../../../components/navigation/userNavBar'; |
|
8 |
import { faFileLines } from '@fortawesome/free-solid-svg-icons'; |
|
9 |
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; |
|
10 |
import { LoggedUserContext } from '../../../contexts/LoggedUserContext'; |
|
11 |
import { MainLayout } from '../../../layouts/mainLayout'; |
|
12 |
|
|
13 |
function UserDocumentPage() { |
|
14 |
const redirecting = useUnauthRedirect('/login'); |
|
15 |
const { logout, role } = useContext(LoggedUserContext); |
|
16 |
const router = useRouter(); |
|
17 |
|
|
18 |
useEffect(() => { |
|
19 |
if (role !== 'ANNOTATOR') { |
|
20 |
logout(); |
|
21 |
router.push('/login'); |
|
22 |
} |
|
23 |
|
|
24 |
if (!redirecting) { |
|
25 |
// TODO load documents |
|
26 |
} |
|
27 |
}, [logout, redirecting, role, router]); |
|
28 |
|
|
29 |
return redirecting || role !== 'ANNOTATOR' ? null : ( |
|
30 |
<MainLayout> |
|
31 |
<Typography.Title level={2}> |
|
32 |
<FontAwesomeIcon icon={faFileLines} /> Dokumenty |
|
33 |
</Typography.Title> |
|
34 |
</MainLayout> |
|
35 |
); |
|
36 |
} |
|
37 |
|
|
38 |
export default UserDocumentPage; |
webapp/pages/export/index.tsx | ||
---|---|---|
1 |
import 'antd/dist/antd.css'; |
|
2 |
import React, { useContext, useEffect } from 'react'; |
|
3 |
|
|
4 |
import { useUnauthRedirect } from '../../hooks'; |
|
5 |
import { useRouter } from 'next/router'; |
|
6 |
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; |
|
7 |
import { faFileExport } from '@fortawesome/free-solid-svg-icons'; |
|
8 |
import { Typography } from 'antd'; |
|
9 |
import { LoggedUserContext } from '../../contexts/LoggedUserContext'; |
|
10 |
import { MainLayout } from '../../layouts/mainLayout'; |
|
11 |
|
|
12 |
function ExportPage() { |
|
13 |
const redirecting = useUnauthRedirect('/login'); |
|
14 |
const { logout, role } = useContext(LoggedUserContext); |
|
15 |
const router = useRouter(); |
|
16 |
|
|
17 |
useEffect(() => { |
|
18 |
if (role !== 'ADMINISTRATOR') { |
|
19 |
logout(); |
|
20 |
router.push('/login'); |
|
21 |
} |
|
22 |
}, [logout, redirecting, role, router]); |
|
23 |
|
|
24 |
return redirecting || role !== 'ADMINISTRATOR' ? null : ( |
|
25 |
<MainLayout> |
|
26 |
<Typography.Title level={2}> |
|
27 |
<FontAwesomeIcon icon={faFileExport} /> Export |
|
28 |
</Typography.Title> |
|
29 |
</MainLayout> |
|
30 |
); |
|
31 |
} |
|
32 |
|
|
33 |
export default ExportPage; |
webapp/pages/index.tsx | ||
---|---|---|
1 | 1 |
import type { NextPage } from 'next'; |
2 |
import Head from 'next/head'; |
|
3 |
import Image from 'next/image'; |
|
4 |
import styles from '../styles/Home.module.css'; |
|
2 |
import { useRouter } from 'next/router'; |
|
3 |
import { useContext, useEffect } from 'react'; |
|
4 |
import { LoggedUserContext } from '../contexts/LoggedUserContext'; |
|
5 |
import { getToken } from '../utils/login'; |
|
5 | 6 |
|
6 | 7 |
const Home: NextPage = () => { |
7 |
return ( |
|
8 |
<div className={styles.container}> |
|
9 |
<Head> |
|
10 |
<title>Create Next App</title> |
|
11 |
<meta name="description" content="Generated by create next app" /> |
|
12 |
<link rel="icon" href="/favicon.ico" /> |
|
13 |
</Head> |
|
14 |
|
|
15 |
<main className={styles.main}> |
|
16 |
<h1 className={styles.title}> |
|
17 |
Welcome to <a href="https://nextjs.org">Next.js!</a> |
|
18 |
</h1> |
|
19 |
|
|
20 |
<div>test {'ahoj'}</div> |
|
21 |
<p className={styles.description}> |
|
22 |
Get started by editing{' '} |
|
23 |
<code className={styles.code}>pages/index.tsx</code> |
|
24 |
</p> |
|
25 |
|
|
26 |
<div className={styles.grid}> |
|
27 |
<a href="https://nextjs.org/docs" className={styles.card}> |
|
28 |
<h2>Documentation →</h2> |
|
29 |
<p>Find in-depth information about Next.js features and API.</p> |
|
30 |
</a> |
|
31 |
|
|
32 |
<a href="https://nextjs.org/learn" className={styles.card}> |
|
33 |
<h2>Learn →</h2> |
|
34 |
<p>Learn about Next.js in an interactive course with quizzes!</p> |
|
35 |
</a> |
|
36 |
|
|
37 |
<a |
|
38 |
href="https://github.com/vercel/next.js/tree/canary/examples" |
|
39 |
className={styles.card} |
|
40 |
> |
|
41 |
<h2>Examples →</h2> |
|
42 |
<p>Discover and deploy boilerplate example Next.js projects.</p> |
|
43 |
</a> |
|
44 |
|
|
45 |
<a |
|
46 |
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app" |
|
47 |
className={styles.card} |
|
48 |
> |
|
49 |
<h2>Deploy →</h2> |
|
50 |
<p> |
|
51 |
Instantly deploy your Next.js site to a public URL with |
|
52 |
Vercel. |
|
53 |
</p> |
|
54 |
</a> |
|
55 |
</div> |
|
56 |
</main> |
|
57 |
|
|
58 |
<footer className={styles.footer}> |
|
59 |
<a |
|
60 |
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app" |
|
61 |
target="_blank" |
|
62 |
rel="noopener noreferrer" |
|
63 |
> |
|
64 |
Powered by{' '} |
|
65 |
<span className={styles.logo}> |
|
66 |
<Image |
|
67 |
src="/vercel.svg" |
|
68 |
alt="Vercel Logo" |
|
69 |
width={72} |
|
70 |
height={16} |
|
71 |
/> |
|
72 |
</span> |
|
73 |
</a> |
|
74 |
</footer> |
|
75 |
</div> |
|
76 |
); |
|
8 |
const { role } = useContext(LoggedUserContext); |
|
9 |
const router = useRouter(); |
|
10 |
|
|
11 |
useEffect(() => { |
|
12 |
async function checkToken() { |
|
13 |
let token = await getToken(); |
|
14 |
if ((await getToken()) === '') { |
|
15 |
router.push('/login'); |
|
16 |
} else { |
|
17 |
if (role === 'ADMINISTRATOR') { |
|
18 |
router.push('/documents/admin'); |
|
19 |
} else if (role === 'ANNOTATOR') { |
|
20 |
router.push('/documents/annotator'); |
|
21 |
} |
|
22 |
} |
|
23 |
} |
|
24 |
|
|
25 |
checkToken(); |
|
26 |
}, [role, router]); |
|
27 |
|
|
28 |
return null; |
|
77 | 29 |
}; |
78 | 30 |
|
79 | 31 |
export default Home; |
webapp/pages/login/index.tsx | ||
---|---|---|
1 |
import 'antd/dist/antd.css'; |
|
1 | 2 |
import { Form, Input, Button } from 'antd'; |
2 | 3 |
import { UserOutlined, LockOutlined } from '@ant-design/icons'; |
3 |
import 'antd/dist/antd.css'; |
|
4 |
import { LoginLayout } from '../../layouts/LoginLayout'; |
|
4 |
import { LoggedUserContext } from '../../contexts/LoggedUserContext'; |
|
5 |
import { LoginLayout } from '../../layouts/loginLayout'; |
|
6 |
import { useContext } from 'react'; |
|
7 |
import { useRouter } from 'next/router'; |
|
8 |
import { ShowToast } from '../../utils/alerts'; |
|
9 |
import { getTokenData } from '../../utils/login'; |
|
10 |
import { LoginResponse } from '../../api'; |
|
5 | 11 |
|
6 | 12 |
/** |
7 | 13 |
* Creates a login screen. |
8 | 14 |
* @returns Html structure of the login screen. |
9 | 15 |
*/ |
10 | 16 |
function Login() { |
17 |
const { login, role } = useContext(LoggedUserContext); |
|
18 |
const router = useRouter(); |
|
11 | 19 |
/** |
12 | 20 |
* Handles submission a form when its fields were successfully validated. |
13 | 21 |
* @param values Fields of the login form. |
14 | 22 |
*/ |
15 |
const onFinish = (values: any) => { |
|
16 |
/** |
|
17 |
@todo: delete login form log when login API is implemented |
|
18 |
**/ |
|
19 |
console.log('Values of the login form: ', values); |
|
23 |
const onFinish = async (values: any) => { |
|
24 |
const loginRes = await login(values.username, values.password); |
|
25 |
|
|
26 |
if (!loginRes) { |
|
27 |
ShowToast( |
|
28 |
'Chybně zadané heslo nebo uživatelské jméno', |
|
29 |
'error', |
|
30 |
3000, |
|
31 |
'top-end' |
|
32 |
); |
|
33 |
} else { |
|
34 |
let data: LoginResponse | null = await getTokenData(); |
|
35 |
ShowToast('Přihlášení proběhlo úspěšně', 'success', 3000, 'top-end'); |
|
36 |
if (data?.role === 'ADMINISTRATOR') { |
|
37 |
await router.push('/documents/admin'); |
|
38 |
} else if (data?.role === 'ANNOTATOR') { |
|
39 |
await router.push('/documents/annotator'); |
|
40 |
} |
|
41 |
} |
|
20 | 42 |
}; |
21 | 43 |
|
22 | 44 |
/** |
... | ... | |
24 | 46 |
* @param errorInfo Validation errors. |
25 | 47 |
*/ |
26 | 48 |
const onFinishFailed = (errorInfo: any) => { |
27 |
/** |
|
28 |
@todo: delete log when error handling is implemented |
|
29 |
**/ |
|
30 |
console.log('Errors: ', errorInfo); |
|
49 |
ShowToast('Zadané údaje nejsou validní', 'error', 3000, 'top-end'); |
|
31 | 50 |
}; |
32 | 51 |
|
33 | 52 |
return ( |
webapp/pages/tags/index.tsx | ||
---|---|---|
1 |
import 'antd/dist/antd.css'; |
|
2 |
import React, { useContext, useEffect } from 'react'; |
|
3 |
|
|
4 |
import { useUnauthRedirect } from '../../hooks'; |
|
5 |
import { useRouter } from 'next/router'; |
|
6 |
import { Typography } from 'antd'; |
|
7 |
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; |
|
8 |
import { faTags } from '@fortawesome/free-solid-svg-icons'; |
|
9 |
import { LoggedUserContext } from '../../contexts/LoggedUserContext'; |
|
10 |
import { MainLayout } from '../../layouts/mainLayout'; |
|
11 |
|
|
12 |
function TagsPage() { |
|
13 |
const redirecting = useUnauthRedirect('/login'); |
|
14 |
const { logout, role } = useContext(LoggedUserContext); |
|
15 |
const router = useRouter(); |
|
16 |
|
|
17 |
useEffect(() => { |
|
18 |
if (role !== 'ADMINISTRATOR') { |
|
19 |
logout(); |
|
20 |
router.push('/login'); |
|
21 |
} |
|
22 |
}, [logout, redirecting, role, router]); |
|
23 |
|
|
24 |
return redirecting || role !== 'ADMINISTRATOR' ? null : ( |
|
25 |
<MainLayout> |
|
26 |
<Typography.Title level={2}> |
|
27 |
<FontAwesomeIcon icon={faTags} /> Značky |
|
28 |
</Typography.Title> |
|
29 |
</MainLayout> |
|
30 |
); |
|
31 |
} |
|
32 |
|
|
33 |
export default TagsPage; |
webapp/pages/users/index.tsx | ||
---|---|---|
1 |
import 'antd/dist/antd.css'; |
|
2 |
import React, { useContext, useEffect } from 'react'; |
|
3 |
|
|
4 |
import { useUnauthRedirect } from '../../hooks'; |
|
5 |
import { useRouter } from 'next/router'; |
|
6 |
import { Typography } from 'antd'; |
|
7 |
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; |
|
8 |
import { faUsers } from '@fortawesome/free-solid-svg-icons'; |
|
9 |
import { LoggedUserContext } from '../../contexts/LoggedUserContext'; |
|
10 |
import { MainLayout } from '../../layouts/mainLayout'; |
|
11 |
|
|
12 |
function UsersPage() { |
|
13 |
const redirecting = useUnauthRedirect('/login'); |
|
14 |
const { logout, role } = useContext(LoggedUserContext); |
|
15 |
const router = useRouter(); |
|
16 |
|
|
17 |
useEffect(() => { |
|
18 |
if (role !== 'ADMINISTRATOR') { |
|
19 |
logout(); |
|
20 |
router.push('/login'); |
|
21 |
} |
|
22 |
}, [logout, redirecting, role, router]); |
|
23 |
|
|
24 |
return redirecting || role !== 'ADMINISTRATOR' ? null : ( |
|
25 |
<MainLayout> |
|
26 |
<Typography.Title level={2}> |
|
27 |
<FontAwesomeIcon icon={faUsers} /> Uživatelé |
|
28 |
</Typography.Title> |
|
29 |
</MainLayout> |
|
30 |
); |
|
31 |
} |
|
32 |
|
|
33 |
export default UsersPage; |
webapp/styles/MainLayout.module.scss | ||
---|---|---|
3 | 3 |
display: grid; |
4 | 4 |
|
5 | 5 |
grid: |
6 |
[header-start] 'header' 60px [header-end]
|
|
6 |
[header-start] 'header' 50px [header-end]
|
|
7 | 7 |
[main-start] 'content' [main-end] |
8 | 8 |
[footer-start] 'footer' 30px [footer-end]; |
9 | 9 |
|
webapp/utils/alerts.ts | ||
---|---|---|
1 |
import Swal, { SweetAlertIcon, SweetAlertPosition } from 'sweetalert2'; |
|
2 |
import withReactContent from 'sweetalert2-react-content'; |
|
3 |
|
|
4 |
const MySwal = withReactContent(Swal); |
|
5 |
|
|
6 |
export function ShowToast( |
|
7 |
text: string, |
|
8 |
icon: SweetAlertIcon = 'success', |
|
9 |
timer = 3000, |
|
10 |
position: SweetAlertPosition = 'top-right' |
|
11 |
) { |
|
12 |
const Toast = Swal.mixin({ |
|
13 |
toast: true, |
|
14 |
position: position, |
|
15 |
showConfirmButton: false, |
|
16 |
timer: timer, |
|
17 |
timerProgressBar: true, |
|
18 |
didOpen: (toast) => { |
|
19 |
toast.addEventListener('mouseenter', Swal.stopTimer); |
|
20 |
toast.addEventListener('mouseleave', Swal.resumeTimer); |
|
21 |
}, |
|
22 |
}); |
|
23 |
|
|
24 |
Toast.fire({ |
|
25 |
icon: icon, |
|
26 |
title: text, |
|
27 |
}); |
|
28 |
} |
webapp/utils/axios.ts | ||
---|---|---|
1 |
import axiosLib from 'axios'; |
|
2 |
import Router from 'next/router'; |
|
3 |
import { StatusCodes } from 'http-status-codes'; |
|
4 |
import { getToken } from './login'; |
|
5 |
|
|
6 |
export const axios = axiosLib.create({ |
|
7 |
baseURL: 'https://localhost:7241', |
|
8 |
timeout: 60000, |
|
9 |
}); |
|
10 |
|
|
11 |
// Add a request interceptor |
|
12 |
axios.interceptors.request.use(async function (config) { |
|
13 |
const token = await getToken(); |
|
14 |
if (token && config?.headers) { |
|
15 |
config.headers.Authorization = 'Bearer ' + token; |
|
16 |
} |
|
17 |
return config; |
|
18 |
}); |
|
19 |
|
|
20 |
// Add a response interceptor |
|
21 |
axios.interceptors.response.use( |
|
22 |
(response) => response, |
|
23 |
async function (error) { |
|
24 |
const status = error?.response?.status; |
|
25 |
if (status === StatusCodes.UNAUTHORIZED) { |
|
26 |
console.log('Unauthorized, redirecting...'); |
|
27 |
|
|
28 |
if (Router.pathname !== '/') { |
|
29 |
await Router.replace({ |
|
30 |
pathname: '/', |
|
31 |
}); |
|
32 |
} |
|
33 |
} else if (status === StatusCodes.FORBIDDEN) { |
|
34 |
console.log('Forbidden:', error?.response?.config?.url); |
|
35 |
} |
|
36 |
|
|
37 |
throw status; |
|
38 |
} |
|
39 |
); |
webapp/utils/login.ts | ||
---|---|---|
1 |
import { authController } from '../controllers'; |
|
2 |
import { LoginResponse } from '../api'; |
|
3 |
|
|
4 |
export async function loginUser(username: string, password: string): Promise<boolean> { |
|
5 |
try { |
|
6 |
const loginRes = await authController.authLoginPost({ username, password }); |
|
7 |
|
|
8 |
const data: LoginResponse = loginRes.data; |
|
9 |
|
|
10 |
if (data && data.token) { |
|
11 |
localStorage.setItem('token', JSON.stringify(data)); |
|
12 |
return true; |
|
13 |
} |
|
14 |
} catch (e) { |
|
15 |
if (e instanceof Error) { |
|
16 |
if (e.message.includes('status code 401')) { |
|
17 |
return false; |
|
18 |
} |
|
19 |
} |
|
20 |
} |
|
21 |
|
|
22 |
return false; |
|
23 |
} |
|
24 |
|
|
25 |
export async function logoutUser(): Promise<boolean> { |
|
26 |
localStorage.clear(); |
|
27 |
return true; |
|
28 |
} |
|
29 |
export async function getTokenData(): Promise<LoginResponse | null> { |
|
30 |
const dataJSON = localStorage.getItem('token'); |
|
31 |
|
|
32 |
if (!dataJSON) { |
|
33 |
// no token found |
|
34 |
return null; |
|
35 |
} |
|
36 |
|
|
37 |
return JSON.parse(dataJSON); |
|
38 |
} |
|
39 |
export async function getToken(): Promise<string> { |
|
40 |
const data = await getTokenData(); |
|
41 |
if (!data) { |
|
42 |
return ''; |
|
43 |
} |
|
44 |
|
|
45 |
return data.token ?? ''; |
|
46 |
} |
webapp/yarn.lock | ||
---|---|---|
37 | 37 |
resize-observer-polyfill "^1.5.0" |
38 | 38 |
|
39 | 39 |
"@babel/runtime-corejs3@^7.10.2": |
40 |
version "7.17.8"
|
|
41 |
resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.17.8.tgz#d7dd49fb812f29c61c59126da3792d8740d4e284"
|
|
42 |
integrity sha512-ZbYSUvoSF6dXZmMl/CYTMOvzIFnbGfv4W3SEHYgMvNsFTeLaF2gkGAF4K2ddmtSK4Emej+0aYcnSC6N5dPCXUQ==
|
|
40 |
version "7.17.9"
|
|
41 |
resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.17.9.tgz#3d02d0161f0fbf3ada8e88159375af97690f4055"
|
|
42 |
integrity sha512-WxYHHUWF2uZ7Hp1K+D1xQgbgkGUfA+5UPOegEXGt2Y5SMog/rYCVaifLZDbw8UkNXozEqqrZTy6bglL7xTaCOw==
|
|
43 | 43 |
dependencies: |
44 | 44 |
core-js-pure "^3.20.2" |
45 | 45 |
regenerator-runtime "^0.13.4" |
46 | 46 |
|
47 |
"@babel/runtime@^7.10.1", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.8.4":
|
|
47 |
"@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.16", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7":
|
|
48 | 48 |
version "7.17.9" |
49 | 49 |
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72" |
50 | 50 |
integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg== |
51 | 51 |
dependencies: |
52 | 52 |
regenerator-runtime "^0.13.4" |
53 | 53 |
|
54 |
"@babel/runtime@^7.10.2", "@babel/runtime@^7.13.16", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.7": |
|
55 |
version "7.17.8" |
|
56 |
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.8.tgz#3e56e4aff81befa55ac3ac6a0967349fd1c5bca2" |
|
57 |
integrity sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA== |
|
58 |
dependencies: |
|
59 |
regenerator-runtime "^0.13.4" |
|
60 |
|
|
61 | 54 |
"@ctrl/tinycolor@^3.4.0": |
62 | 55 |
version "3.4.1" |
63 | 56 |
resolved "https://registry.yarnpkg.com/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz#75b4c27948c81e88ccd3a8902047bcd797f38d32" |
... | ... | |
78 | 71 |
minimatch "^3.0.4" |
79 | 72 |
strip-json-comments "^3.1.1" |
80 | 73 |
|
81 |
"@fortawesome/fontawesome-free@^6.1.0": |
|
82 |
version "6.1.0" |
|
83 |
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.1.0.tgz#db162f63c6fdb3ecc6d44de3bbc8ed178390d709" |
|
84 |
integrity sha512-OgM74M6+Q7BuKAj8r+VfzwjnIGZrY62R4ipbiDvBW4FA0mLnB3yeuV/2bW63j+zppGyTvBp/3jqXp9ZXy43nFw== |
|
74 |
"@fortawesome/fontawesome-common-types@6.1.1": |
|
75 |
version "6.1.1" |
|
76 |
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.1.1.tgz#7dc996042d21fc1ae850e3173b5c67b0549f9105" |
|
77 |
integrity sha512-wVn5WJPirFTnzN6tR95abCx+ocH+3IFLXAgyavnf9hUmN0CfWoDjPT/BAWsUVwSlYYVBeCLJxaqi7ZGe4uSjBA== |
|
78 |
|
|
79 |
"@fortawesome/fontawesome-svg-core@^6.1.1": |
|
80 |
version "6.1.1" |
|
81 |
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.1.1.tgz#3424ec6182515951816be9b11665d67efdce5b5f" |
|
82 |
integrity sha512-NCg0w2YIp81f4V6cMGD9iomfsIj7GWrqmsa0ZsPh59G7PKiGN1KymZNxmF00ssuAlo/VZmpK6xazsGOwzKYUMg== |
|
83 |
dependencies: |
|
84 |
"@fortawesome/fontawesome-common-types" "6.1.1" |
|
85 |
|
|
86 |
"@fortawesome/free-solid-svg-icons@^6.1.1": |
|
87 |
version "6.1.1" |
|
88 |
resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.1.1.tgz#3369e673f8fe8be2fba30b1ec274d47490a830a6" |
|
89 |
integrity sha512-0/5exxavOhI/D4Ovm2r3vxNojGZioPwmFrKg0ZUH69Q68uFhFPs6+dhAToh6VEQBntxPRYPuT5Cg1tpNa9JUPg== |
|
90 |
dependencies: |
|
91 |
"@fortawesome/fontawesome-common-types" "6.1.1" |
|
92 |
|
|
93 |
"@fortawesome/react-fontawesome@^0.1.18": |
|
94 |
version "0.1.18" |
|
95 |
resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.18.tgz#dae37f718a24e14d7a99a5496c873d69af3fbd73" |
|
96 |
integrity sha512-RwLIB4TZw0M9gvy5u+TusAA0afbwM4JQIimNH/j3ygd6aIvYPQLqXMhC9ErY26J23rDPyDZldIfPq/HpTTJ/tQ== |
|
97 |
dependencies: |
|
98 |
prop-types "^15.8.1" |
|
85 | 99 |
|
86 | 100 |
"@humanwhocodes/config-array@^0.9.2": |
87 | 101 |
version "0.9.5" |
... | ... | |
97 | 111 |
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" |
98 | 112 |
integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== |
99 | 113 |
|
114 |
"@nestjs/common@8.2.6": |
|
115 |
version "8.2.6" |
|
116 |
resolved "https://registry.yarnpkg.com/@nestjs/common/-/common-8.2.6.tgz#34cd5cc44082d3525c56c95db42ca0e5277b7d85" |
|
117 |
integrity sha512-flLYSXunxcKyjbYddrhwbc49uE705MxBt85rS3mHyhDbAIPSGGeZEqME44YyAzCg1NTfJSNe7ztmOce5kNkb9A== |
|
118 |
dependencies: |
|
119 |
axios "0.24.0" |
|
120 |
iterare "1.2.1" |
|
121 |
tslib "2.3.1" |
|
122 |
uuid "8.3.2" |
|
123 |
|
|
124 |
"@nestjs/core@8.2.6": |
|
125 |
version "8.2.6" |
|
126 |
resolved "https://registry.yarnpkg.com/@nestjs/core/-/core-8.2.6.tgz#08eb38203fb01a828227ea25972d38bfef5c818f" |
|
127 |
integrity sha512-NwPcEIMmCsucs3QaDlQvkoU1FlFM2wm/WjaqLQhkSoIEmAR1gNtBo88f5io5cpMwCo1k5xYhqGlaSl6TfngwWQ== |
|
128 |
dependencies: |
|
129 |
"@nuxtjs/opencollective" "0.3.2" |
|
130 |
fast-safe-stringify "2.1.1" |
|
131 |
iterare "1.2.1" |
|
132 |
object-hash "2.2.0" |
|
133 |
path-to-regexp "3.2.0" |
|
134 |
tslib "2.3.1" |
|
135 |
uuid "8.3.2" |
|
136 |
|
|
100 | 137 |
"@next/env@12.1.0": |
101 | 138 |
version "12.1.0" |
102 | 139 |
resolved "https://registry.yarnpkg.com/@next/env/-/env-12.1.0.tgz#73713399399b34aa5a01771fb73272b55b22c314" |
... | ... | |
185 | 222 |
"@nodelib/fs.scandir" "2.1.5" |
186 | 223 |
fastq "^1.6.0" |
187 | 224 |
|
225 |
"@nuxtjs/opencollective@0.3.2": |
|
226 |
version "0.3.2" |
|
227 |
resolved "https://registry.yarnpkg.com/@nuxtjs/opencollective/-/opencollective-0.3.2.tgz#620ce1044f7ac77185e825e1936115bb38e2681c" |
|
228 |
integrity sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA== |
|
229 |
dependencies: |
|
230 |
chalk "^4.1.0" |
|
231 |
consola "^2.15.0" |
|
232 |
node-fetch "^2.6.1" |
|
233 |
|
|
234 |
"@openapitools/openapi-generator-cli@2.4.26": |
|
235 |
version "2.4.26" |
|
236 |
resolved "https://registry.yarnpkg.com/@openapitools/openapi-generator-cli/-/openapi-generator-cli-2.4.26.tgz#67622fc41c258aeae3ff074cd92772978e03484f" |
|
237 |
integrity sha512-O42H9q1HWGoIpcpMaUu318b6bmOgcjP3MieHwOrFdoG3KyttceBGlbLf9Kbf7WM91WSNCDXum7cnEKASuoGjAg== |
|
238 |
dependencies: |
|
239 |
"@nestjs/common" "8.2.6" |
|
240 |
"@nestjs/core" "8.2.6" |
|
241 |
"@nuxtjs/opencollective" "0.3.2" |
|
242 |
chalk "4.1.2" |
|
243 |
commander "8.3.0" |
|
244 |
compare-versions "3.6.0" |
|
245 |
concurrently "6.5.1" |
|
246 |
console.table "0.10.0" |
|
247 |
fs-extra "10.0.0" |
|
248 |
glob "7.1.6" |
|
249 |
inquirer "8.2.0" |
|
250 |
lodash "4.17.21" |
|
251 |
reflect-metadata "0.1.13" |
|
252 |
rxjs "7.5.2" |
|
253 |
tslib "2.0.3" |
|
254 |
|
|
188 | 255 |
"@popperjs/core@^2.10.1": |
189 |
version "2.11.4"
|
|
190 |
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.4.tgz#d8c7b8db9226d2d7664553a0741ad7d0397ee503"
|
|
191 |
integrity sha512-q/ytXxO5NKvyT37pmisQAItCFqA7FD/vNb8dgaJy3/630Fsc+Mz9/9f2SziBoIZ30TJooXyTwZmhi1zjXmObYg==
|
|
256 |
version "2.11.5"
|
|
257 |
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.5.tgz#db5a11bf66bdab39569719555b0f76e138d7bd64"
|
|
258 |
integrity sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==
|
|
192 | 259 |
|
193 | 260 |
"@react-aria/ssr@^3.0.1": |
194 | 261 |
version "3.1.2" |
... | ... | |
197 | 264 |
dependencies: |
198 | 265 |
"@babel/runtime" "^7.6.2" |
199 | 266 |
|
200 |
"@restart/hooks@^0.4.0", "@restart/hooks@^0.4.5":
|
|
201 |
version "0.4.5"
|
|
202 |
resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.4.5.tgz#e7acbea237bfc9e479970500cf87538b41a1ed02"
|
|
203 |
integrity sha512-tLGtY0aHeIfT7aPwUkvQuhIy3+q3w4iqmUzFLPlOAf/vNUacLaBt1j/S//jv/dQhenRh8jvswyMojCwmLvJw8A==
|
|
267 |
"@restart/hooks@^0.4.0", "@restart/hooks@^0.4.6":
|
|
268 |
version "0.4.6"
|
|
269 |
resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.4.6.tgz#15dcf34631a618c513efc924705c7cbe349a4a0c"
|
|
270 |
integrity sha512-FzpEzy6QeLB3OpUrC9OQD/lWCluQmilLfRGa/DqbB6OmV05AEt/0Lgn3Jf6l27UIJMK0qFmNcps6p8DNLXa6Pw==
|
|
204 | 271 |
dependencies: |
205 | 272 |
dequal "^2.0.2" |
206 | 273 |
|
207 |
"@restart/ui@^1.0.2":
|
|
208 |
version "1.1.0"
|
|
209 |
resolved "https://registry.yarnpkg.com/@restart/ui/-/ui-1.1.0.tgz#46d436225162b47ecccdf191cfbcf9ec3d1d5f47"
|
|
210 |
integrity sha512-sYAO1LP78Suz5cT2VEkU4U/mvdjFXNg69QHanc5OAFTWyhCBG2lFJ9FITZ7hT8P8LPqcWXcwEGzHhuxPUDDDYQ==
|
|
274 |
"@restart/ui@^1.2.0":
|
|
275 |
version "1.2.0"
|
|
276 |
resolved "https://registry.yarnpkg.com/@restart/ui/-/ui-1.2.0.tgz#fb90251aa25f99b41ccedc78a91d2a15f3c5e0fb"
|
|
277 |
integrity sha512-oIh2t3tG8drZtZ9SlaV5CY6wGsUViHk8ZajjhcI+74IQHyWy+AnxDv8rJR5wVgsgcgrPBUvGNkC1AEdcGNPaLQ==
|
|
211 | 278 |
dependencies: |
212 | 279 |
"@babel/runtime" "^7.13.16" |
213 | 280 |
"@popperjs/core" "^2.10.1" |
... | ... | |
216 | 283 |
"@types/warning" "^3.0.0" |
217 | 284 |
dequal "^2.0.2" |
218 | 285 |
dom-helpers "^5.2.0" |
219 |
prop-types "^15.7.2" |
|
220 | 286 |
uncontrollable "^7.2.1" |
221 | 287 |
warning "^4.0.3" |
222 | 288 |
|
223 | 289 |
"@rushstack/eslint-patch@^1.0.8": |
224 |
version "1.1.1" |
|
225 |
resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.1.tgz#782fa5da44c4f38ae9fd38e9184b54e451936118" |
|
226 |
integrity sha512-BUyKJGdDWqvWC5GEhyOiUrGNi9iJUr4CU0O2WxJL6QJhHeeA/NVBalH+FeK0r/x/W0rPymXt5s78TDS7d6lCwg== |
|
290 |
version "1.1.3" |
|
291 |
resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.3.tgz#6801033be7ff87a6b7cadaf5b337c9f366a3c4b0" |
|
292 |
integrity sha512-WiBSI6JBIhC6LRIsB2Kwh8DsGTlbBU+mLRxJmAe3LjHTdkDpwIbEOZgoXBbZilk/vlfjK8i6nKRAvIRn1XaIMw== |
|
293 |
|
|
294 |
"@types/cookie@^0.3.3": |
|
295 |
version "0.3.3" |
|
296 |
resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.3.3.tgz#85bc74ba782fb7aa3a514d11767832b0e3bc6803" |
|
297 |
integrity sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow== |
|
298 |
|
|
299 |
"@types/hoist-non-react-statics@^3.0.1": |
|
300 |
version "3.3.1" |
|
301 |
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" |
|
302 |
integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== |
|
303 |
dependencies: |
|
304 |
"@types/react" "*" |
|
305 |
hoist-non-react-statics "^3.3.0" |
|
227 | 306 |
|
228 | 307 |
"@types/invariant@^2.2.35": |
229 | 308 |
version "2.2.35" |
... | ... | |
241 | 320 |
integrity sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ== |
242 | 321 |
|
243 | 322 |
"@types/prop-types@*", "@types/prop-types@^15.7.4": |
244 |
version "15.7.4"
|
|
245 |
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11"
|
|
246 |
integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==
|
|
323 |
version "15.7.5"
|
|
324 |
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
|
|
325 |
integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
|
|
247 | 326 |
|
248 | 327 |
"@types/react-transition-group@^4.4.4": |
249 | 328 |
version "4.4.4" |
... | ... | |
252 | 331 |
dependencies: |
253 | 332 |
"@types/react" "*" |
254 | 333 |
|
255 |
"@types/react@*", "@types/react@17.0.41", "@types/react@>=16.14.8", "@types/react@>=16.9.11": |
|
334 |
"@types/react@*", "@types/react@>=16.14.8", "@types/react@>=16.9.11": |
|
335 |
version "18.0.5" |
|
336 |
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.5.tgz#1a4d4b705ae6af5aed369dec22800b20f89f5301" |
|
337 |
integrity sha512-UPxNGInDCIKlfqBrm8LDXYWNfLHwIdisWcsH5GpMyGjhEDLFgTtlRBaoWuCua9HcyuE0rMkmAeZ3FXV1pYLIYQ== |
|
338 |
dependencies: |
|
339 |
"@types/prop-types" "*" |
|
340 |
"@types/scheduler" "*" |
|
341 |
csstype "^3.0.2" |
|
342 |
|
|
343 |
"@types/react@17.0.41": |
|
256 | 344 |
version "17.0.41" |
257 | 345 |
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.41.tgz#6e179590d276394de1e357b3f89d05d7d3da8b85" |
258 | 346 |
integrity sha512-chYZ9ogWUodyC7VUTRBfblysKLjnohhFY9bGLwvnUFFy48+vB9DikmB3lW0qTFmBcKSzmdglcvkHK71IioOlDA== |
... | ... | |
272 | 360 |
integrity sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI= |
273 | 361 |
|
274 | 362 |
"@typescript-eslint/parser@^5.0.0": |
275 |
version "5.15.0"
|
|
276 |
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.15.0.tgz#95f603f8fe6eca7952a99bfeef9b85992972e728"
|
|
277 |
integrity sha512-NGAYP/+RDM2sVfmKiKOCgJYPstAO40vPAgACoWPO/+yoYKSgAXIFaBKsV8P0Cc7fwKgvj27SjRNX4L7f4/jCKQ==
|
|
363 |
version "5.19.0"
|
|
364 |
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.19.0.tgz#05e587c1492868929b931afa0cb5579b0f728e75"
|
|
365 |
integrity sha512-yhktJjMCJX8BSBczh1F/uY8wGRYrBeyn84kH6oyqdIJwTGKmzX5Qiq49LRQ0Jh0LXnWijEziSo6BRqny8nqLVQ==
|
|
278 | 366 |
dependencies: |
279 |
"@typescript-eslint/scope-manager" "5.15.0"
|
|
280 |
"@typescript-eslint/types" "5.15.0"
|
|
281 |
"@typescript-eslint/typescript-estree" "5.15.0"
|
|
367 |
"@typescript-eslint/scope-manager" "5.19.0"
|
|
368 |
"@typescript-eslint/types" "5.19.0"
|
|
369 |
"@typescript-eslint/typescript-estree" "5.19.0"
|
|
282 | 370 |
debug "^4.3.2" |
283 | 371 |
|
284 |
"@typescript-eslint/scope-manager@5.15.0":
|
|
285 |
version "5.15.0"
|
|
286 |
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.15.0.tgz#d97afab5e0abf4018d1289bd711be21676cdd0ee"
|
|
287 |
integrity sha512-EFiZcSKrHh4kWk0pZaa+YNJosvKE50EnmN4IfgjkA3bTHElPtYcd2U37QQkNTqwMCS7LXeDeZzEqnsOH8chjSg==
|
|
372 |
"@typescript-eslint/scope-manager@5.19.0":
|
|
373 |
version "5.19.0"
|
|
374 |
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.19.0.tgz#97e59b0bcbcb54dbcdfba96fc103b9020bbe9cb4"
|
|
375 |
integrity sha512-Fz+VrjLmwq5fbQn5W7cIJZ066HxLMKvDEmf4eu1tZ8O956aoX45jAuBB76miAECMTODyUxH61AQM7q4/GOMQ5g==
|
|
288 | 376 |
dependencies: |
289 |
"@typescript-eslint/types" "5.15.0"
|
|
290 |
"@typescript-eslint/visitor-keys" "5.15.0"
|
|
377 |
"@typescript-eslint/types" "5.19.0"
|
|
378 |
"@typescript-eslint/visitor-keys" "5.19.0"
|
|
291 | 379 |
|
292 |
"@typescript-eslint/types@5.15.0":
|
|
293 |
version "5.15.0"
|
|
294 |
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.15.0.tgz#c7bdd103843b1abae97b5518219d3e2a0d79a501"
|
|
295 |
integrity sha512-yEiTN4MDy23vvsIksrShjNwQl2vl6kJeG9YkVJXjXZnkJElzVK8nfPsWKYxcsGWG8GhurYXP4/KGj3aZAxbeOA==
|
|
380 |
"@typescript-eslint/types@5.19.0":
|
|
381 |
version "5.19.0"
|
|
382 |
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.19.0.tgz#12d3d600d754259da771806ee8b2c842d3be8d12"
|
|
383 |
integrity sha512-zR1ithF4Iyq1wLwkDcT+qFnhs8L5VUtjgac212ftiOP/ZZUOCuuF2DeGiZZGQXGoHA50OreZqLH5NjDcDqn34w==
|
|
296 | 384 |
|
297 |
"@typescript-eslint/typescript-estree@5.15.0":
|
|
298 |
version "5.15.0"
|
|
299 |
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.15.0.tgz#81513a742a9c657587ad1ddbca88e76c6efb0aac"
|
|
300 |
integrity sha512-Hb0e3dGc35b75xLzixM3cSbG1sSbrTBQDfIScqdyvrfJZVEi4XWAT+UL/HMxEdrJNB8Yk28SKxPLtAhfCbBInA==
|
|
385 |
"@typescript-eslint/typescript-estree@5.19.0":
|
|
386 |
version "5.19.0"
|
|
387 |
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.19.0.tgz#fc987b8f62883f9ea6a5b488bdbcd20d33c0025f"
|
|
388 |
integrity sha512-dRPuD4ocXdaE1BM/dNR21elSEUPKaWgowCA0bqJ6YbYkvtrPVEvZ+zqcX5a8ECYn3q5iBSSUcBBD42ubaOp0Hw==
|
|
301 | 389 |
dependencies: |
302 |
"@typescript-eslint/types" "5.15.0"
|
|
303 |
"@typescript-eslint/visitor-keys" "5.15.0"
|
|
390 |
"@typescript-eslint/types" "5.19.0"
|
|
391 |
"@typescript-eslint/visitor-keys" "5.19.0"
|
|
304 | 392 |
debug "^4.3.2" |
305 | 393 |
globby "^11.0.4" |
306 | 394 |
is-glob "^4.0.3" |
307 | 395 |
semver "^7.3.5" |
308 | 396 |
tsutils "^3.21.0" |
309 | 397 |
|
310 |
"@typescript-eslint/visitor-keys@5.15.0":
|
|
311 |
version "5.15.0"
|
|
312 |
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.15.0.tgz#5669739fbf516df060f978be6a6dce75855a8027"
|
|
313 |
integrity sha512-+vX5FKtgvyHbmIJdxMJ2jKm9z2BIlXJiuewI8dsDYMp5LzPUcuTT78Ya5iwvQg3VqSVdmxyM8Anj1Jeq7733ZQ==
|
|
398 |
"@typescript-eslint/visitor-keys@5.19.0":
|
|
399 |
version "5.19.0"
|
|
400 |
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.19.0.tgz#c84ebc7f6c744707a361ca5ec7f7f64cd85b8af6"
|
|
401 |
integrity sha512-Ym7zZoMDZcAKWsULi2s7UMLREdVQdScPQ/fKWMYefarCztWlHPFVJo8racf8R0Gc8FAEJ2eD4of8As1oFtnQlQ==
|
|
314 | 402 |
dependencies: |
315 |
"@typescript-eslint/types" "5.15.0"
|
|
403 |
"@typescript-eslint/types" "5.19.0"
|
|
316 | 404 |
eslint-visitor-keys "^3.0.0" |
317 | 405 |
|
318 | 406 |
acorn-jsx@^5.3.1: |
... | ... | |
335 | 423 |
json-schema-traverse "^0.4.1" |
336 | 424 |
uri-js "^4.2.2" |
337 | 425 |
|
426 |
ansi-escapes@^4.2.1: |
|
427 |
version "4.3.2" |
|
428 |
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" |
|
429 |
integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== |
|
430 |
dependencies: |
|
431 |
type-fest "^0.21.3" |
|
432 |
|
|
338 | 433 |
ansi-regex@^5.0.1: |
339 | 434 |
version "5.0.1" |
340 | 435 |
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" |
341 | 436 |
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== |
342 | 437 |
|
343 |
ansi-styles@^4.1.0: |
|
438 |
ansi-styles@^4.0.0, ansi-styles@^4.1.0:
|
|
344 | 439 |
version "4.3.0" |
345 | 440 |
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" |
346 | 441 |
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== |
... | ... | |
417 | 512 |
"@babel/runtime" "^7.10.2" |
418 | 513 |
"@babel/runtime-corejs3" "^7.10.2" |
419 | 514 |
|
420 |
array-includes@^3.1.3, array-includes@^3.1.4:
|
|
515 |
array-includes@^3.1.4: |
|
421 | 516 |
version "3.1.4" |
422 | 517 |
resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9" |
423 | 518 |
integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw== |
... | ... | |
439 | 534 |
integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== |
440 | 535 |
|
441 | 536 |
array.prototype.flat@^1.2.5: |
442 |
version "1.2.5"
|
|
443 |
resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13"
|
|
444 |
integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==
|
|
537 |
version "1.3.0"
|
|
538 |
resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz#0b0c1567bf57b38b56b4c97b8aa72ab45e4adc7b"
|
|
539 |
integrity sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==
|
|
445 | 540 |
dependencies: |
446 | 541 |
call-bind "^1.0.2" |
447 | 542 |
define-properties "^1.1.3" |
448 |
es-abstract "^1.19.0" |
|
543 |
es-abstract "^1.19.2" |
|
544 |
es-shim-unscopables "^1.0.0" |
|
449 | 545 |
|
450 | 546 |
array.prototype.flatmap@^1.2.5: |
451 |
version "1.2.5"
|
|
452 |
resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz#908dc82d8a406930fdf38598d51e7411d18d4446"
|
|
453 |
integrity sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==
|
|
547 |
version "1.3.0"
|
|
548 |
resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz#a7e8ed4225f4788a70cd910abcf0791e76a5534f"
|
|
549 |
integrity sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==
|
|
454 | 550 |
dependencies: |
455 |
call-bind "^1.0.0"
|
|
551 |
call-bind "^1.0.2"
|
|
456 | 552 |
define-properties "^1.1.3" |
457 |
es-abstract "^1.19.0" |
|
553 |
es-abstract "^1.19.2" |
|
554 |
es-shim-unscopables "^1.0.0" |
|
458 | 555 |
|
459 | 556 |
ast-types-flow@^0.0.7: |
460 | 557 |
version "0.0.7" |
... | ... | |
471 | 568 |
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.4.1.tgz#7dbdc25989298f9ad006645cd396782443757413" |
472 | 569 |
integrity sha512-gd1kmb21kwNuWr6BQz8fv6GNECPBnUasepcoLbekws23NVBLODdsClRZ+bQ8+9Uomf3Sm3+Vwn0oYG9NvwnJCw== |
473 | 570 |
|
571 |
axios@0.24.0: |
|
572 |
version "0.24.0" |
|
573 |
resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6" |
|
574 |
integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA== |
|
575 |
dependencies: |
|
576 |
follow-redirects "^1.14.4" |
|
577 |
|
Také k dispozici: Unified diff
Token management implemented, redirections