Skip to content
This repository was archived by the owner on May 13, 2025. It is now read-only.

Commit be9f528

Browse files
add OAuth Support (#132)
Also adds new users and roles page. Part of parseablehq/parseable#410
1 parent f6c3461 commit be9f528

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1564
-542
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@
2222
"@mantine/prism": "^6.0.15",
2323
"@monaco-editor/react": "^4.5.1",
2424
"@tabler/icons-react": "^2.23.0",
25+
"@types/js-cookie": "^3.0.3",
2526
"axios": "^1.4.0",
2627
"dayjs": "^1.11.8",
2728
"http-status-codes": "^2.2.0",
2829
"immer": "^10.0.2",
30+
"js-cookie": "^3.0.5",
2931
"just-compare": "^2.3.0",
3032
"ms": "^2.1.3",
3133
"react": "^18.2.0",

pnpm-lock.yaml

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/AGPLv3_Logo.svg

Lines changed: 28 additions & 0 deletions
Loading

src/api/auth.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { Axios } from './axios';
2-
import { LOG_STREAM_LIST_URL } from './constants';
2+
import { LOGIN_URL } from './constants';
3+
34

45
export const loginIn = (username: string, password: string) => {
56
const credentials = btoa(`${username}:${password}`);
67

7-
return Axios().get(LOG_STREAM_LIST_URL, {
8+
return Axios().get(LOGIN_URL, {
89
headers: {
910
Authorization: `Basic ${credentials}`,
1011
},

src/api/axios.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,10 @@ import axios from 'axios';
22

33
const baseURL = import.meta.env.VITE_PARSEABLE_URL ?? '/';
44

5-
const instance = axios.create({ baseURL, validateStatus: () => true });
5+
const instance = axios.create({ baseURL, validateStatus: () => true, withCredentials: true });
66

77
instance.interceptors.request.use(
88
(request) => {
9-
const credentials = localStorage.getItem('credentials');
10-
11-
if (credentials) {
12-
const Authorization = credentials ? `Basic ${credentials}` : null;
13-
14-
request.headers.Authorization = Authorization;
15-
}
16-
179
return request;
1810
},
1911
(error) => {

src/api/constants.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@ export const USER_URL = (username: string) => `${USERS_LIST_URL}/${username}`;
1818
export const USER_ROLES_URL = (username: string) => `${USER_URL(username)}/role`;
1919
export const USER_PASSWORD_URL = (username: string) => `${USER_URL(username)}/generate-new-password`;
2020

21+
// Roles Management
22+
export const ROLES_LIST_URL = `${API_V1}/role`;
23+
export const ROLE_URL = (roleName: string) => `${ROLES_LIST_URL}/${roleName}`;
24+
25+
26+
//USERS LOGIN
27+
28+
export const LOGIN_URL = `${API_V1}/o/login?redirect=${window.location.origin}`;
29+
2130
// LLM queries
2231
export const LLM_QUERY_URL = `${API_V1}/llm`;
2332
export const IS_LLM_ACTIVE_URL = `${LLM_QUERY_URL}/isactive`;
33+

src/api/roles.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Axios } from "./axios";
2+
import { ROLE_URL, ROLES_LIST_URL } from "./constants";
3+
4+
export const getRoles = () => {
5+
return Axios().get(ROLES_LIST_URL);
6+
}
7+
8+
export const deleteRole = (roleName: string) => {
9+
return Axios().delete(ROLE_URL(roleName));
10+
}
11+
12+
export const putRole = (roleName: string, privilege: object[]) => {
13+
return Axios().put(ROLE_URL(roleName), privilege);
14+
}
15+
16+
export const getRole = (roleName: string) => {
17+
return Axios().get(ROLE_URL(roleName));
18+
}

src/assets/images/login-bg.svg

Lines changed: 1 addition & 1 deletion
Loading

src/components/Header/Layout.tsx

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,18 @@
1-
import logoInvert from '@/assets/images/brand/logo-invert.svg';
2-
import { HOME_ROUTE } from '@/constants/routes';
31
import { HEADER_HEIGHT } from '@/constants/theme';
42
import type { HeaderProps as MantineHeaderProps } from '@mantine/core';
5-
import { Box, Image, Header as MantineHeader } from '@mantine/core';
3+
import { Box, Header as MantineHeader } from '@mantine/core';
64
import { FC } from 'react';
7-
import { Link, Outlet } from 'react-router-dom';
5+
import { Outlet } from 'react-router-dom';
86
import { useHeaderStyles } from './styles';
97

108
type HeaderProps = Omit<MantineHeaderProps, 'children' | 'height' | 'className'>;
119

1210
const HeaderLayout: FC<HeaderProps> = (props) => {
1311
const { classes } = useHeaderStyles();
14-
const { container, logoContainer, navContainer, imageSty } = classes;
12+
const { container, navContainer } = classes;
1513

1614
return (
17-
<MantineHeader {...props} className={container} height={HEADER_HEIGHT} p={0} withBorder>
18-
<Box className={logoContainer}>
19-
<Link to={HOME_ROUTE}>
20-
<Image className={imageSty} src={logoInvert} height={24} alt="Parseable Logo" />
21-
</Link>
22-
</Box>
15+
<MantineHeader {...props} className={container} height={HEADER_HEIGHT} p={0} withBorder zIndex={100}>
2316
<Box className={navContainer}>
2417
<Outlet />
2518
</Box>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import logoInvert from '@/assets/images/brand/logo-invert.svg';
2+
import { HOME_ROUTE } from '@/constants/routes';
3+
import { HEADER_HEIGHT } from '@/constants/theme';
4+
import type { HeaderProps as MantineHeaderProps } from '@mantine/core';
5+
import { Box, Button, Image, Header as MantineHeader, Tooltip } from '@mantine/core';
6+
import { FC } from 'react';
7+
import { Link } from 'react-router-dom';
8+
import { useHeaderStyles } from './styles';
9+
10+
type PrimaryHeaderProps = Omit<MantineHeaderProps, 'children' | 'height' | 'className'>;
11+
12+
const PrimaryHeader: FC<PrimaryHeaderProps> = (props) => {
13+
const { classes } = useHeaderStyles();
14+
const { container, logoContainer, navContainer, imageSty, actionBtn } = classes;
15+
16+
return (
17+
<MantineHeader {...props} className={container} height={HEADER_HEIGHT} p={0} withBorder>
18+
<Box className={logoContainer}>
19+
<Link to={HOME_ROUTE}>
20+
<Image className={imageSty} src={logoInvert} height={24} alt="Parseable Logo" />
21+
</Link>
22+
</Box>
23+
<Box className={navContainer}>
24+
<Box
25+
display={'flex'}
26+
sx={{
27+
justifyContent: 'flex-end',
28+
alignItems: 'center',
29+
width: '100%',
30+
paddingLeft: '1rem',
31+
}}
32+
pr={'xl'}>
33+
<Tooltip label="Upgrade to production support" position="bottom">
34+
<Button
35+
variant="outline"
36+
component={'a'}
37+
href="mailto:[email protected]?subject=Production%20Support%20Query"
38+
target="_blank"
39+
className={actionBtn}>
40+
<Image height={30} fit="fill" src={'/AGPLv3_Logo.svg'} />
41+
</Button>
42+
</Tooltip>
43+
</Box>
44+
</Box>
45+
</MantineHeader>
46+
);
47+
};
48+
49+
export default PrimaryHeader;

0 commit comments

Comments
 (0)