integrate automatic token refresh if current one is invalid

--> load login page if token can't be refreshed
This commit is contained in:
lukas 2021-03-16 20:13:12 +01:00
parent a51176fb93
commit e412f699f7
3 changed files with 52 additions and 15 deletions

View File

@ -54,9 +54,25 @@ class App extends React.Component<{}, state> {
password: pwdneeded password: pwdneeded
}; };
// force an update on theme change
GlobalInfos.onThemeChange(() => { GlobalInfos.onThemeChange(() => {
this.forceUpdate(); this.forceUpdate();
}); });
// set the hook to load passwordfield on global func call
GlobalInfos.loadPasswordPage = (callback?: () => void) => {
// try refreshing the token
refreshAPIToken((err) => {
if (err !== '') {
this.setState({password: true});
} else {
// call callback if request was successful
if (callback) {
callback();
}
}
}, true);
};
} }
initialAPICall(): void { initialAPICall(): void {
@ -96,13 +112,17 @@ class App extends React.Component<{}, state> {
return ( return (
<AuthenticationPage <AuthenticationPage
submit={(password): void => { submit={(password): void => {
refreshAPIToken((error) => { refreshAPIToken(
(error) => {
if (error !== '') { if (error !== '') {
console.log('wrong password!!!'); console.log('wrong password!!!');
} else { } else {
this.setState({password: false}); this.setState({password: false});
} }
}, password); },
true,
password
);
}} }}
/> />
); );

View File

@ -1,3 +1,5 @@
import GlobalInfos from './GlobalInfos';
let customBackendURL: string; let customBackendURL: string;
/** /**
@ -57,8 +59,9 @@ let expireSeconds = -1;
* refresh the api token or use that one in cookie if still valid * refresh the api token or use that one in cookie if still valid
* @param callback to be called after successful refresh * @param callback to be called after successful refresh
* @param password * @param password
* @param force
*/ */
export function refreshAPIToken(callback: (error: string) => void, password?: string): void { export function refreshAPIToken(callback: (error: string) => void, force?: boolean, password?: string): void {
callQue.push(callback); callQue.push(callback);
// check if already is a token refresh is in process // check if already is a token refresh is in process
@ -70,7 +73,7 @@ export function refreshAPIToken(callback: (error: string) => void, password?: st
refreshInProcess = true; refreshInProcess = true;
} }
if (apiTokenValid()) { if (apiTokenValid() && !force) {
console.log('token still valid...'); console.log('token still valid...');
callFuncQue(''); callFuncQue('');
return; return;
@ -229,13 +232,22 @@ export function callAPI<T>(
}) })
}) })
.then((response) => { .then((response) => {
if (response.status !== 200) { if (response.status === 200) {
console.log('Error: ' + response.statusText); // success
// todo place error popup here
} else {
response.json().then((result: T) => { response.json().then((result: T) => {
callback(result); callback(result);
}); });
} else if (response.status === 400) {
// Bad Request --> invalid token
console.log('loading Password page.');
// load password page
if (GlobalInfos.loadPasswordPage) {
GlobalInfos.loadPasswordPage(() => {
callAPI(apinode, fd, callback, errorcallback);
});
}
} else {
console.log('Error: ' + response.statusText);
} }
}) })
.catch((reason) => errorcallback(reason)); .catch((reason) => errorcallback(reason));
@ -295,6 +307,7 @@ export function callAPIPlain(apinode: APINode, fd: ApiBaseRequest, callback: (_:
/** /**
* API nodes definitions * API nodes definitions
*/ */
// eslint-disable-next-line no-shadow // eslint-disable-next-line no-shadow
export enum APINode { export enum APINode {
Settings = 'settings', Settings = 'settings',

View File

@ -55,7 +55,11 @@ class StaticInfos {
getVideoPath(): string { getVideoPath(): string {
return this.videopath; return this.videopath;
} }
/**
* load the Password page manually
*/
loadPasswordPage: ((callback?: () => void) => void) | undefined = undefined;
} }
const GlobalInfos = new StaticInfos(); export default new StaticInfos();
export default GlobalInfos;