use some status information to handle errors better
This commit is contained in:
@@ -3,6 +3,7 @@ import { Button } from 'primereact/button';
|
|||||||
import { Card } from 'primereact/card';
|
import { Card } from 'primereact/card';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { Auth, Configuration, Session } from '../services';
|
import { Auth, Configuration, Session } from '../services';
|
||||||
|
import { BackendReturnStatus } from '../types';
|
||||||
|
|
||||||
export const Login: React.FC = () => {
|
export const Login: React.FC = () => {
|
||||||
const [loading, setLoading] = useState<boolean>(true);
|
const [loading, setLoading] = useState<boolean>(true);
|
||||||
@@ -10,8 +11,8 @@ export const Login: React.FC = () => {
|
|||||||
|
|
||||||
// check if the known bearer token is still valid
|
// check if the known bearer token is still valid
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
Auth.tokenIsValid().then((valid) => {
|
Auth.tokenIsValid().then((status) => {
|
||||||
if (!valid) {
|
if (status !== BackendReturnStatus.Ok) {
|
||||||
Session.reset();
|
Session.reset();
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { useNavigate } from 'react-router-dom';
|
|||||||
import { AuthContext, TimeContext } from '../contexts';
|
import { AuthContext, TimeContext } from '../contexts';
|
||||||
import { Configuration } from '../services';
|
import { Configuration } from '../services';
|
||||||
import { Airport } from '../services';
|
import { Airport } from '../services';
|
||||||
import { AirportOverview, IAuthState } from '../types';
|
import { AirportOverview, BackendReturnStatus, IAuthState } from '../types';
|
||||||
|
|
||||||
export const NavBar: React.FC = () => {
|
export const NavBar: React.FC = () => {
|
||||||
const [timestamp, setTimestamp] = useState<string>('');
|
const [timestamp, setTimestamp] = useState<string>('');
|
||||||
@@ -63,7 +63,9 @@ export const NavBar: React.FC = () => {
|
|||||||
const updateMenuItems = async () => {
|
const updateMenuItems = async () => {
|
||||||
if (currentAuth.current === undefined || !currentAuth.current.valid) return [];
|
if (currentAuth.current === undefined || !currentAuth.current.valid) return [];
|
||||||
|
|
||||||
Airport.all().then((airports) => {
|
Airport.all().then((response) => {
|
||||||
|
if (response.status !== BackendReturnStatus.Ok) return [];
|
||||||
|
|
||||||
const newMenuTree: { label: string; items?: any[]; command?: () => void }[] = [
|
const newMenuTree: { label: string; items?: any[]; command?: () => void }[] = [
|
||||||
{
|
{
|
||||||
label: 'Airports',
|
label: 'Airports',
|
||||||
@@ -72,12 +74,12 @@ export const NavBar: React.FC = () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// create the airports subtree
|
// create the airports subtree
|
||||||
const airportSubtree = firBasedSubMenu(airports, '/sequence');
|
const airportSubtree = firBasedSubMenu(response.airports, '/sequence');
|
||||||
newMenuTree[0].items = airportSubtree;
|
newMenuTree[0].items = airportSubtree;
|
||||||
|
|
||||||
// collect all configuration airports
|
// collect all configuration airports
|
||||||
const configurationAirports: AirportOverview[] = [];
|
const configurationAirports: AirportOverview[] = [];
|
||||||
airports.forEach((airport) => {
|
response.airports.forEach((airport) => {
|
||||||
const idx = currentAuth.current?.user.airportConfigurationAccess.findIndex((value) => airport.icao === value);
|
const idx = currentAuth.current?.user.airportConfigurationAccess.findIndex((value) => airport.icao === value);
|
||||||
if (idx !== -1) configurationAirports.push(airport);
|
if (idx !== -1) configurationAirports.push(airport);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { createContext, Dispatch, SetStateAction, useEffect, useState } from 'react';
|
import { createContext, Dispatch, SetStateAction, useEffect, useState } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { Auth } from '../services';
|
import { Auth } from '../services';
|
||||||
import { IAuthState } from '../types';
|
import { BackendReturnStatus, IAuthState } from '../types';
|
||||||
|
|
||||||
const InitialAuthState: IAuthState = {
|
const InitialAuthState: IAuthState = {
|
||||||
valid: false,
|
valid: false,
|
||||||
@@ -27,9 +27,9 @@ export const AuthProvider = ({ children }: { children: any }) => {
|
|||||||
const resetAuth = () => setAuth(InitialAuthState);
|
const resetAuth = () => setAuth(InitialAuthState);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
Auth.user().then((user) => {
|
Auth.user().then((response) => {
|
||||||
if (user !== undefined) {
|
if (response.status === BackendReturnStatus.Ok) {
|
||||||
setAuth({ valid: true, user });
|
setAuth({ valid: true, user: response.user });
|
||||||
} else {
|
} else {
|
||||||
setAuth(InitialAuthState);
|
setAuth(InitialAuthState);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,21 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Configuration } from './configuration';
|
import { Configuration } from './configuration';
|
||||||
import { Session } from './session';
|
import { Session } from './session';
|
||||||
import { AirportOverview } from '../types';
|
import {
|
||||||
|
AirportOverviewBackend,
|
||||||
|
AirportOverview,
|
||||||
|
BackendReturnStatus,
|
||||||
|
} from '../types';
|
||||||
|
|
||||||
export class Airport {
|
export class Airport {
|
||||||
static async all(): Promise<AirportOverview[]> {
|
static async all(): Promise<AirportOverviewBackend> {
|
||||||
const token = Session.bearerToken();
|
const token = Session.bearerToken();
|
||||||
if (!token) return [];
|
if (!token) {
|
||||||
|
return {
|
||||||
|
status: BackendReturnStatus.Unauthorized,
|
||||||
|
airports: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return axios
|
return axios
|
||||||
.get<AirportOverview[]>(`${Configuration.resourceServer}/airport/all`, {
|
.get<AirportOverview[]>(`${Configuration.resourceServer}/airport/all`, {
|
||||||
@@ -14,7 +23,17 @@ export class Airport {
|
|||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((response) => response.data)
|
.then((response) => {
|
||||||
.catch(() => []);
|
return {
|
||||||
|
status: BackendReturnStatus.Ok,
|
||||||
|
airports: response.data,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
return {
|
||||||
|
status: err.status === 401 ? BackendReturnStatus.Unauthorized : BackendReturnStatus.Failure,
|
||||||
|
airports: [],
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Configuration } from './configuration';
|
import { Configuration } from './configuration';
|
||||||
import { Session } from './session';
|
import { Session } from './session';
|
||||||
import { User } from '../types';
|
import {
|
||||||
|
BackendReturnStatus,
|
||||||
|
DefaultUser,
|
||||||
|
UserBackend,
|
||||||
|
User,
|
||||||
|
} from '../types';
|
||||||
|
|
||||||
export class Auth {
|
export class Auth {
|
||||||
static async tokenIsValid(): Promise<boolean> {
|
static async tokenIsValid(): Promise<BackendReturnStatus> {
|
||||||
const token = Session.bearerToken();
|
const token = Session.bearerToken();
|
||||||
if (!token) return false;
|
if (!token) return BackendReturnStatus.Unauthorized;
|
||||||
|
|
||||||
return axios
|
return axios
|
||||||
.get<void>(`${Configuration.resourceServer}/auth/validate`, {
|
.get<void>(`${Configuration.resourceServer}/auth/validate`, {
|
||||||
@@ -14,13 +19,21 @@ export class Auth {
|
|||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(() => true)
|
.then(() => BackendReturnStatus.Ok)
|
||||||
.catch(() => false);
|
.catch((err) => {
|
||||||
|
if (err.status === 401) return BackendReturnStatus.Unauthorized;
|
||||||
|
return BackendReturnStatus.Failure;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static async user(): Promise<User | undefined> {
|
static async user(): Promise<UserBackend> {
|
||||||
const token = Session.bearerToken();
|
const token = Session.bearerToken();
|
||||||
if (!token) return undefined;
|
if (!token) {
|
||||||
|
return {
|
||||||
|
status: BackendReturnStatus.Unauthorized,
|
||||||
|
user: DefaultUser,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return axios
|
return axios
|
||||||
.get<User>(`${Configuration.resourceServer}/auth/user`, {
|
.get<User>(`${Configuration.resourceServer}/auth/user`, {
|
||||||
@@ -28,7 +41,31 @@ export class Auth {
|
|||||||
Authorization: `Bearer ${token}`,
|
Authorization: `Bearer ${token}`,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then((response) => response.data)
|
.then((response) => {
|
||||||
.catch(() => undefined);
|
return {
|
||||||
|
status: BackendReturnStatus.Ok,
|
||||||
|
user: response.data,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
return {
|
||||||
|
status: err.status === 401 ? BackendReturnStatus.Unauthorized : BackendReturnStatus.Failure,
|
||||||
|
user: DefaultUser,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static async refreshRadarScopeKey(): Promise<boolean> {
|
||||||
|
const token = Session.bearerToken();
|
||||||
|
if (!token) return false;
|
||||||
|
|
||||||
|
return axios
|
||||||
|
.get<void>(`${Configuration.resourceServer}/auth/refreshRadarScopeKey`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${token}`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(() => true)
|
||||||
|
.catch(() => false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,20 @@
|
|||||||
|
export enum BackendReturnStatus {
|
||||||
|
Ok,
|
||||||
|
Unauthorized,
|
||||||
|
Failure,
|
||||||
|
};
|
||||||
|
|
||||||
export interface AirportOverview {
|
export interface AirportOverview {
|
||||||
icao: string;
|
icao: string;
|
||||||
name: string;
|
name: string;
|
||||||
flightInformationRegion: string;
|
flightInformationRegion: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export interface AirportOverviewBackend {
|
||||||
|
status: BackendReturnStatus;
|
||||||
|
airports: AirportOverview[];
|
||||||
|
};
|
||||||
|
|
||||||
export interface User {
|
export interface User {
|
||||||
vatsimId: string;
|
vatsimId: string;
|
||||||
fullName: string;
|
fullName: string;
|
||||||
@@ -12,6 +23,19 @@ export interface User {
|
|||||||
airportConfigurationAccess: string[];
|
airportConfigurationAccess: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const DefaultUser: User = {
|
||||||
|
vatsimId: '',
|
||||||
|
fullName: '',
|
||||||
|
radarScopeKey: '',
|
||||||
|
administrator: false,
|
||||||
|
airportConfigurationAccess: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface UserBackend {
|
||||||
|
status: BackendReturnStatus;
|
||||||
|
user: User;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IAuthState {
|
export interface IAuthState {
|
||||||
valid: boolean,
|
valid: boolean,
|
||||||
user: User,
|
user: User,
|
||||||
|
|||||||
Reference in New Issue
Block a user