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
};
// force an update on theme change
GlobalInfos.onThemeChange(() => {
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 {
@ -96,13 +112,17 @@ class App extends React.Component<{}, state> {
return (
<AuthenticationPage
submit={(password): void => {
refreshAPIToken((error) => {
if (error !== '') {
console.log('wrong password!!!');
} else {
this.setState({password: false});
}
}, password);
refreshAPIToken(
(error) => {
if (error !== '') {
console.log('wrong password!!!');
} else {
this.setState({password: false});
}
},
true,
password
);
}}
/>
);

View File

@ -1,3 +1,5 @@
import GlobalInfos from './GlobalInfos';
let customBackendURL: string;
/**
@ -57,8 +59,9 @@ let expireSeconds = -1;
* refresh the api token or use that one in cookie if still valid
* @param callback to be called after successful refresh
* @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);
// 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;
}
if (apiTokenValid()) {
if (apiTokenValid() && !force) {
console.log('token still valid...');
callFuncQue('');
return;
@ -229,13 +232,22 @@ export function callAPI<T>(
})
})
.then((response) => {
if (response.status !== 200) {
console.log('Error: ' + response.statusText);
// todo place error popup here
} else {
if (response.status === 200) {
// success
response.json().then((result: T) => {
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));
@ -295,6 +307,7 @@ export function callAPIPlain(apinode: APINode, fd: ApiBaseRequest, callback: (_:
/**
* API nodes definitions
*/
// eslint-disable-next-line no-shadow
export enum APINode {
Settings = 'settings',

View File

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