2024-08-27 09:28:24 -07:00
|
|
|
import "./App.css";
|
2024-08-27 09:39:28 -07:00
|
|
|
import "bootstrap/dist/css/bootstrap.min.css";
|
2024-08-27 10:48:49 -07:00
|
|
|
import * as base64 from "base-64";
|
2024-08-27 14:00:30 -07:00
|
|
|
import { Client } from "jmap-client-ts";
|
2024-08-27 15:45:33 -07:00
|
|
|
import { IAccount, ISession } from "jmap-client-ts/lib/types";
|
2024-08-27 14:00:30 -07:00
|
|
|
import { FetchTransport } from "jmap-client-ts/lib/utils/fetch-transport";
|
2024-08-26 16:07:43 -07:00
|
|
|
|
2024-08-27 14:38:15 -07:00
|
|
|
import AccountList from "./AccountList";
|
2024-08-27 09:28:24 -07:00
|
|
|
import AuthModal from "./AuthModal";
|
2024-08-27 15:45:33 -07:00
|
|
|
import React from "react";
|
2024-08-27 09:28:24 -07:00
|
|
|
|
|
|
|
interface IAuth {
|
2024-08-27 11:11:54 -07:00
|
|
|
email: string;
|
2024-08-27 09:39:28 -07:00
|
|
|
password: string;
|
2024-08-27 08:23:58 -07:00
|
|
|
}
|
|
|
|
|
2024-08-27 15:45:33 -07:00
|
|
|
interface ILocation {
|
|
|
|
accountId: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
type AppState = {
|
2024-08-27 14:00:30 -07:00
|
|
|
auth: IAuth;
|
2024-08-27 15:45:33 -07:00
|
|
|
location: ILocation;
|
2024-08-27 14:38:15 -07:00
|
|
|
session: ISession | null;
|
2024-08-27 15:45:33 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
type AppProps = {};
|
2024-08-27 14:00:30 -07:00
|
|
|
|
2024-08-27 15:45:33 -07:00
|
|
|
class App extends React.Component<AppProps, AppState> {
|
|
|
|
account(): IAccount | null {
|
|
|
|
if (!(this.state.session && this.state.session.accounts)) return null;
|
|
|
|
return this.state.session.accounts[this.state.location.accountId];
|
|
|
|
}
|
|
|
|
client: Client | null = null;
|
|
|
|
state: AppState = {
|
2024-08-27 14:11:00 -07:00
|
|
|
auth: { email: "", password: "" },
|
2024-08-27 15:45:33 -07:00
|
|
|
location: { accountId: "" },
|
2024-08-27 14:38:15 -07:00
|
|
|
session: null,
|
2024-08-27 11:11:54 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
// Make the request to get system metadata
|
2024-08-27 15:45:33 -07:00
|
|
|
doLogin(auth: IAuth) {
|
2024-08-27 11:11:54 -07:00
|
|
|
const domain = auth.email.split("@")[1];
|
2024-08-27 14:00:30 -07:00
|
|
|
const well_known_url = "https://" + domain + "/.well-known/jmap";
|
|
|
|
const basic_auth =
|
|
|
|
"Basic " + base64.encode(auth.email + ":" + auth.password);
|
|
|
|
|
2024-08-27 15:45:33 -07:00
|
|
|
this.client = new Client({
|
2024-08-27 14:00:30 -07:00
|
|
|
accessToken: "fake token",
|
|
|
|
httpHeaders: { Authorization: basic_auth },
|
|
|
|
sessionUrl: well_known_url,
|
|
|
|
transport: new FetchTransport(fetch.bind(window)),
|
|
|
|
});
|
2024-08-27 14:11:00 -07:00
|
|
|
|
2024-08-27 15:45:33 -07:00
|
|
|
this.client
|
2024-08-27 14:00:30 -07:00
|
|
|
.fetchSession()
|
2024-08-27 14:38:15 -07:00
|
|
|
.then(() => {
|
2024-08-27 15:45:33 -07:00
|
|
|
console.log("Session received");
|
|
|
|
|
|
|
|
// For the type checker
|
|
|
|
if (!this.client) return;
|
|
|
|
|
|
|
|
const session = this.client.getSession();
|
|
|
|
this.setState({
|
|
|
|
...this.state,
|
|
|
|
session: session,
|
|
|
|
});
|
2024-08-27 14:38:15 -07:00
|
|
|
})
|
2024-08-27 14:00:30 -07:00
|
|
|
.catch((error) => console.error(error));
|
|
|
|
|
|
|
|
return;
|
2024-08-27 15:45:33 -07:00
|
|
|
}
|
2024-08-27 09:39:28 -07:00
|
|
|
|
2024-08-27 15:45:33 -07:00
|
|
|
onHashChange() {
|
|
|
|
console.log(window.location.hash);
|
|
|
|
const hash = window.location.hash.substring(1);
|
|
|
|
this.setState({
|
|
|
|
...this.state,
|
|
|
|
location: { accountId: hash },
|
|
|
|
});
|
|
|
|
}
|
|
|
|
// When the user provides credentials
|
|
|
|
onLogin(email: string, password: string) {
|
|
|
|
// Store the provided credentials for now
|
|
|
|
this.setState({
|
|
|
|
...this.state,
|
|
|
|
auth: {
|
|
|
|
email: email,
|
|
|
|
password: password,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
localStorage.setItem("auth", JSON.stringify(this.state.auth));
|
|
|
|
this.doLogin({ email, password });
|
|
|
|
}
|
|
|
|
|
|
|
|
loadAuth() {
|
2024-08-27 11:11:54 -07:00
|
|
|
const data = localStorage.getItem("auth");
|
|
|
|
if (!data) return;
|
|
|
|
const auth = JSON.parse(data);
|
2024-08-27 15:45:33 -07:00
|
|
|
this.setState({
|
|
|
|
...this.state,
|
|
|
|
auth: auth,
|
|
|
|
});
|
|
|
|
if (this.client == null) {
|
|
|
|
this.doLogin(auth);
|
2024-08-27 14:11:00 -07:00
|
|
|
return;
|
|
|
|
}
|
2024-08-27 15:45:33 -07:00
|
|
|
}
|
2024-08-27 09:39:28 -07:00
|
|
|
|
2024-08-27 15:45:33 -07:00
|
|
|
componentDidMount() {
|
|
|
|
window.addEventListener(
|
|
|
|
"hashchange",
|
|
|
|
() => {
|
|
|
|
this.onHashChange();
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
);
|
|
|
|
this.loadAuth();
|
|
|
|
this.onHashChange();
|
|
|
|
}
|
|
|
|
|
|
|
|
componentWillUnmount() {
|
|
|
|
window.removeEventListener(
|
|
|
|
"hashchange",
|
|
|
|
() => {
|
|
|
|
this.onHashChange();
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
<div className="App">
|
2024-08-27 17:05:10 -07:00
|
|
|
{this.state && this.state.session ? (
|
2024-08-27 15:45:33 -07:00
|
|
|
<AccountList
|
|
|
|
account={this.account()}
|
2024-08-27 17:05:10 -07:00
|
|
|
accounts={this.state.session.accounts}
|
2024-08-27 15:45:33 -07:00
|
|
|
/>
|
|
|
|
) : (
|
|
|
|
<AuthModal onLogin={this.onLogin}></AuthModal>
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2024-07-31 20:58:46 -07:00
|
|
|
|
|
|
|
export default App;
|