Fix bug get current user (#115)
* Fix bug get current user * Add tests * Fix design on Workspace section in Navbar
This commit is contained in:
@ -9,11 +9,13 @@ import RequireAuth from './components/auth/RequireAuth';
|
|||||||
import Opportunities from './pages/opportunities/Opportunities';
|
import Opportunities from './pages/opportunities/Opportunities';
|
||||||
import { User, mapUser } from './interfaces/user.interface';
|
import { User, mapUser } from './interfaces/user.interface';
|
||||||
import { useGetCurrentUserQuery } from './services/users';
|
import { useGetCurrentUserQuery } from './services/users';
|
||||||
|
import { getUserIdFromToken } from './services/AuthService';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [user, setUser] = useState<User | undefined>(undefined);
|
const [user, setUser] = useState<User | undefined>(undefined);
|
||||||
|
|
||||||
const { data } = useGetCurrentUserQuery();
|
const userIdFromToken = getUserIdFromToken();
|
||||||
|
const { data } = useGetCurrentUserQuery(userIdFromToken);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data?.users[0]) {
|
if (data?.users[0]) {
|
||||||
|
|||||||
@ -10,12 +10,18 @@ const component = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
localStorage.setItem('refreshToken', 'xxx-refresh');
|
localStorage.setItem('refreshToken', 'xxx-refresh');
|
||||||
localStorage.setItem('accessToken', 'xxx-access');
|
localStorage.setItem(
|
||||||
|
'accessToken',
|
||||||
|
'eyJhbGciOiJIUzI1NiJ9.eyJodHRwczovL2hhc3VyYS5pby9qd3QvY2xhaW1zIjp7IngtaGFzdXJhLXdvcmtzcGFjZS1pZCI6IjdlZDlkMjEyLTFjMjUtNGQwMi1iZjI1LTZhZWNjZjdlYTQxOSIsIngtaGFzdXJhLWFsbG93ZWQtcm9sZXMiOlsibWUiLCJ1c2VyIl0sIngtaGFzdXJhLWRlZmF1bHQtcm9sZSI6InVzZXIiLCJ4LWhhc3VyYS11c2VyLWlkIjoiMTY1MDZiYTgtMTk2Yy00YzEzLWE0YTctYTIyY2I1ZWNjZmExIiwieC1oYXN1cmEtdXNlci1pcy1hbm9ueW1vdXMiOiJmYWxzZSJ9LCJzdWIiOiIxNjUwNmJhOC0xOTZjLTRjMTMtYTRhNy1hMjJjYjVlY2NmYTEiLCJpYXQiOjE2ODM4NzM5NzIsImV4cCI6MTY4Mzg3NDg3MiwiaXNzIjoiaGFzdXJhLWF1dGgifQ.C_OynseOprgU-SdLBLzMdfg_441eopI7LYg8yB86g3c',
|
||||||
|
);
|
||||||
|
|
||||||
const mocks = [
|
const mocks = [
|
||||||
{
|
{
|
||||||
request: {
|
request: {
|
||||||
query: GET_CURRENT_USER,
|
query: GET_CURRENT_USER,
|
||||||
|
variables: {
|
||||||
|
uuid: '16506ba8-196c-4c13-a4a7-a22cb5eccfa1',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
result: {
|
result: {
|
||||||
data: {
|
data: {
|
||||||
|
|||||||
@ -7,7 +7,6 @@ type OwnProps = {
|
|||||||
|
|
||||||
const StyledContainer = styled.button`
|
const StyledContainer = styled.button`
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
width: min-content;
|
|
||||||
height: 34px;
|
height: 34px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -17,6 +16,7 @@ const StyledContainer = styled.button`
|
|||||||
border-radius: ${(props) => props.theme.spacing(1)};
|
border-radius: ${(props) => props.theme.spacing(1)};
|
||||||
padding: ${(props) => props.theme.spacing(2)};
|
padding: ${(props) => props.theme.spacing(2)};
|
||||||
margin-left: ${(props) => props.theme.spacing(1)};
|
margin-left: ${(props) => props.theme.spacing(1)};
|
||||||
|
align-self: flex-start;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
type StyledLogoProps = {
|
type StyledLogoProps = {
|
||||||
@ -36,7 +36,6 @@ const StyledName = styled.div`
|
|||||||
font-family: 'Inter';
|
font-family: 'Inter';
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-size: ${(props) => props.theme.fontSizeLarge};
|
font-size: ${(props) => props.theme.fontSizeLarge};
|
||||||
font-color: ${(props) => props.theme.text0};
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
function WorkspaceContainer({ workspace }: OwnProps) {
|
function WorkspaceContainer({ workspace }: OwnProps) {
|
||||||
|
|||||||
@ -1,9 +1,24 @@
|
|||||||
|
import jwt from 'jwt-decode';
|
||||||
|
|
||||||
export const hasAccessToken = () => {
|
export const hasAccessToken = () => {
|
||||||
const accessToken = localStorage.getItem('accessToken');
|
const accessToken = localStorage.getItem('accessToken');
|
||||||
|
|
||||||
return accessToken ? true : false;
|
return accessToken ? true : false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getUserIdFromToken: () => string | null = () => {
|
||||||
|
const accessToken = localStorage.getItem('accessToken');
|
||||||
|
if (!accessToken) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return jwt<{ sub: string }>(accessToken).sub;
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const hasRefreshToken = () => {
|
export const hasRefreshToken = () => {
|
||||||
const refreshToken = localStorage.getItem('refreshToken');
|
const refreshToken = localStorage.getItem('refreshToken');
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import {
|
|||||||
hasAccessToken,
|
hasAccessToken,
|
||||||
hasRefreshToken,
|
hasRefreshToken,
|
||||||
refreshAccessToken,
|
refreshAccessToken,
|
||||||
|
getUserIdFromToken,
|
||||||
} from '../AuthService';
|
} from '../AuthService';
|
||||||
|
|
||||||
const mockFetch = async (
|
const mockFetch = async (
|
||||||
@ -63,6 +64,26 @@ it('refreshToken refreshes the token if refresh token is valid', async () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('getUserIdFromToken returns null when the token is not present', async () => {
|
||||||
|
const userId = getUserIdFromToken();
|
||||||
|
expect(userId).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('getUserIdFromToken returns null when the token is not valid', async () => {
|
||||||
|
localStorage.setItem('accessToken', 'xxx-invalid-access');
|
||||||
|
const userId = getUserIdFromToken();
|
||||||
|
expect(userId).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('getUserIdFromToken returns the right userId when the token is valid', async () => {
|
||||||
|
localStorage.setItem(
|
||||||
|
'accessToken',
|
||||||
|
'eyJhbGciOiJIUzI1NiJ9.eyJodHRwczovL2hhc3VyYS5pby9qd3QvY2xhaW1zIjp7IngtaGFzdXJhLXdvcmtzcGFjZS1pZCI6IjdlZDlkMjEyLTFjMjUtNGQwMi1iZjI1LTZhZWNjZjdlYTQxOSIsIngtaGFzdXJhLWFsbG93ZWQtcm9sZXMiOlsibWUiLCJ1c2VyIl0sIngtaGFzdXJhLWRlZmF1bHQtcm9sZSI6InVzZXIiLCJ4LWhhc3VyYS11c2VyLWlkIjoiMTY1MDZiYTgtMTk2Yy00YzEzLWE0YTctYTIyY2I1ZWNjZmExIiwieC1oYXN1cmEtdXNlci1pcy1hbm9ueW1vdXMiOiJmYWxzZSJ9LCJzdWIiOiIxNjUwNmJhOC0xOTZjLTRjMTMtYTRhNy1hMjJjYjVlY2NmYTEiLCJpYXQiOjE2ODM4NzM5NzIsImV4cCI6MTY4Mzg3NDg3MiwiaXNzIjoiaGFzdXJhLWF1dGgifQ.C_OynseOprgU-SdLBLzMdfg_441eopI7LYg8yB86g3c',
|
||||||
|
);
|
||||||
|
const userId = getUserIdFromToken();
|
||||||
|
expect(userId).toBe('16506ba8-196c-4c13-a4a7-a22cb5eccfa1');
|
||||||
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2,8 +2,8 @@ import { QueryResult, gql, useQuery } from '@apollo/client';
|
|||||||
import { GraphqlQueryUser } from '../../interfaces/user.interface';
|
import { GraphqlQueryUser } from '../../interfaces/user.interface';
|
||||||
|
|
||||||
export const GET_CURRENT_USER = gql`
|
export const GET_CURRENT_USER = gql`
|
||||||
query GetCurrentUser {
|
query GetCurrentUser($uuid: uuid) {
|
||||||
users {
|
users(where: { id: { _eq: $uuid } }) {
|
||||||
id
|
id
|
||||||
email
|
email
|
||||||
displayName
|
displayName
|
||||||
@ -19,8 +19,12 @@ export const GET_CURRENT_USER = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export function useGetCurrentUserQuery(): QueryResult<{
|
export function useGetCurrentUserQuery(userId: string | null): QueryResult<{
|
||||||
users: GraphqlQueryUser[];
|
users: GraphqlQueryUser[];
|
||||||
}> {
|
}> {
|
||||||
return useQuery<{ users: GraphqlQueryUser[] }>(GET_CURRENT_USER);
|
return useQuery<{ users: GraphqlQueryUser[] }>(GET_CURRENT_USER, {
|
||||||
|
variables: {
|
||||||
|
uuid: userId,
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -133,10 +133,35 @@ select_permissions:
|
|||||||
- role: user
|
- role: user
|
||||||
permission:
|
permission:
|
||||||
columns:
|
columns:
|
||||||
|
- disabled
|
||||||
|
- email_verified
|
||||||
|
- is_anonymous
|
||||||
|
- phone_number_verified
|
||||||
|
- locale
|
||||||
|
- metadata
|
||||||
|
- active_mfa_type
|
||||||
|
- avatar_url
|
||||||
|
- default_role
|
||||||
- display_name
|
- display_name
|
||||||
|
- otp_hash
|
||||||
|
- otp_method_last_used
|
||||||
|
- password_hash
|
||||||
|
- phone_number
|
||||||
|
- ticket
|
||||||
|
- totp_secret
|
||||||
|
- webauthn_current_challenge
|
||||||
|
- created_at
|
||||||
|
- last_seen
|
||||||
|
- otp_hash_expires_at
|
||||||
|
- ticket_expires_at
|
||||||
|
- updated_at
|
||||||
- email
|
- email
|
||||||
|
- new_email
|
||||||
- id
|
- id
|
||||||
filter: {}
|
filter:
|
||||||
|
workspace_member:
|
||||||
|
workspace_id:
|
||||||
|
_eq: X-Hasura-Workspace-Id
|
||||||
event_triggers:
|
event_triggers:
|
||||||
- name: user-created
|
- name: user-created
|
||||||
definition:
|
definition:
|
||||||
|
|||||||
Reference in New Issue
Block a user