blob: ea55c3a29b107c56aceeba2cfe138999a169b661 [file] [log] [blame]
/* eslint-disable no-undef */
// TODO: This hides eslint errors for this file. This should be removed once this file is cleaned up.
/*
* Copyright (c) 2017-2021 Savoir-faire Linux Inc.
*
* Author: Adrien BĂ©raud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
class AuthManager {
constructor() {
console.log('AuthManager()');
this.authenticating = false;
this.state = {
initialized: false,
authenticated: true,
setupComplete: true,
error: false,
};
this.tasks = [];
this.onAuthChanged = undefined;
if (initData) {
console.log('Using static initData');
this.setInitData(initData);
return;
}
}
isAuthenticated() {
return this.state.authenticated;
}
getState() {
return this.state;
}
setInitData(data) {
this.authenticating = false;
this.state.initialized = true;
if (data.username) {
Object.assign(this.state, {
authenticated: true,
setupComplete: true,
error: false,
user: { username: data.username, type: data.type },
});
} else {
Object.assign(this.state, {
authenticated: false,
setupComplete: 'setupComplete' in data ? data.setupComplete : true,
error: false,
});
}
console.log('Init ended');
/*if (this.onAuthChanged)
this.onAuthChanged(this.state)*/
}
init(cb) {
this.onAuthChanged = cb;
if (this.state.initialized || this.authenticating) return;
/*if (initData) {
console.log("Using static initData")
this.setInitData(initData)
return
}*/
this.authenticating = true;
fetch('/auth')
.then(async (response) => {
this.authenticating = false;
this.state.initialized = true;
if (response.status === 200) {
this.setInitData(await response.json());
} else if (response.status === 401) {
this.setInitData(await response.json());
} else {
this.state.error = true;
if (this.onAuthChanged) this.onAuthChanged(this.state);
}
})
.catch((e) => {
this.authenticating = false;
console.log(e);
});
}
deinit() {
console.log('Deinit');
this.onAuthChanged = undefined;
}
async setup(password) {
if (this.authenticating || this.state.setupComplete) return;
console.log('Starting setup');
this.authenticating = true;
const response = await fetch(`/setup`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ password }),
});
console.log(response);
if (response.ok) {
console.log('Success, going home');
//navigate('/')
}
this.authenticating = false;
this.state.setupComplete = true;
if (this.onAuthChanged) this.onAuthChanged(this.state);
return response.ok;
}
authenticate(username, password) {
if (this.authenticating) return;
console.log('Starting authentication');
this.authenticating = true;
fetch(`/auth/local?username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}`, {
method: 'POST',
})
.then((response) => {
console.log(response);
this.authenticating = false;
this.state.authenticated = response.ok && response.status === 200;
if (this.onAuthChanged) this.onAuthChanged(this.state);
while (this.tasks.length !== 0) {
const task = this.tasks.shift();
if (this.state.authenticated)
fetch(task.url, task.init)
.then((res) => task.resolve(res))
.catch((e) => console.log('Error executing pending task: ' + e));
else task.reject(new Error('Authentication failed'));
}
})
.catch((e) => {
this.authenticating = false;
console.log(e);
});
}
disconnect() {
console.log('Disconnect');
this.state.authenticated = false;
if (this.onAuthChanged) this.onAuthChanged(this.state);
}
fetch(url, init) {
console.log(`fetch ${url}`);
if (!this.state.authenticated) {
if (!init || !init.method || init.method === 'GET') {
return new Promise((resolve, reject) => this.tasks.push({ url, init, resolve, reject }));
} else {
return new Promise((resolve, reject) => reject('Not authenticated'));
}
}
return fetch(url, init).then((response) => {
if (response.status === 401) {
this.disconnect();
return this.fetch(url, init);
}
return response;
});
}
}
export default new AuthManager();