Etebase change to login.
parent
6d18d494a7
commit
1817fbf87d
@ -1,104 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: © 2017 EteSync Authors
|
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
|
|
||||||
import * as React from "react";
|
|
||||||
import Button from "@material-ui/core/Button";
|
|
||||||
import TextField from "@material-ui/core/TextField";
|
|
||||||
|
|
||||||
interface FormErrors {
|
|
||||||
errorEncryptionPassword?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
class EncryptionLoginForm extends React.PureComponent {
|
|
||||||
public state: {
|
|
||||||
errors: FormErrors;
|
|
||||||
encryptionPassword: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
public props: {
|
|
||||||
onSubmit: (encryptionPassword: string) => void;
|
|
||||||
loading?: boolean;
|
|
||||||
error?: Error;
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(props: any) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
errors: {},
|
|
||||||
encryptionPassword: "",
|
|
||||||
};
|
|
||||||
this.generateEncryption = this.generateEncryption.bind(this);
|
|
||||||
this.handleInputChange = this.handleInputChange.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public handleInputChange(event: React.ChangeEvent<any>) {
|
|
||||||
const name = event.target.name;
|
|
||||||
const value = event.target.value;
|
|
||||||
this.setState({
|
|
||||||
[name]: value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public generateEncryption(e: any) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
const encryptionPassword = this.state.encryptionPassword;
|
|
||||||
|
|
||||||
const errors: FormErrors = {};
|
|
||||||
const fieldRequired = "This field is required!";
|
|
||||||
if (!encryptionPassword) {
|
|
||||||
errors.errorEncryptionPassword = fieldRequired;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Object.keys(errors).length) {
|
|
||||||
this.setState({ errors });
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
this.setState({ errors: {} });
|
|
||||||
}
|
|
||||||
|
|
||||||
this.props.onSubmit(encryptionPassword);
|
|
||||||
}
|
|
||||||
|
|
||||||
public render() {
|
|
||||||
const styles = {
|
|
||||||
form: {
|
|
||||||
},
|
|
||||||
submit: {
|
|
||||||
marginTop: 40,
|
|
||||||
textAlign: "right" as any,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<React.Fragment>
|
|
||||||
{(this.props.error) && (<div>Error! {this.props.error.message}</div>)}
|
|
||||||
<form style={styles.form} onSubmit={this.generateEncryption}>
|
|
||||||
<TextField
|
|
||||||
type="password"
|
|
||||||
autoFocus
|
|
||||||
error={!!this.state.errors.errorEncryptionPassword}
|
|
||||||
helperText={this.state.errors.errorEncryptionPassword}
|
|
||||||
label="Encryption Password"
|
|
||||||
name="encryptionPassword"
|
|
||||||
value={this.state.encryptionPassword}
|
|
||||||
onChange={this.handleInputChange}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div style={styles.submit}>
|
|
||||||
<Button
|
|
||||||
type="submit"
|
|
||||||
variant="contained"
|
|
||||||
color="secondary"
|
|
||||||
disabled={this.props.loading}
|
|
||||||
>
|
|
||||||
{this.props.loading ? "Loading…" : "Continue"}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default EncryptionLoginForm;
|
|
@ -0,0 +1,26 @@
|
|||||||
|
// SPDX-FileCopyrightText: © 2017 Etebase Authors
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import { createSelector } from "reselect";
|
||||||
|
|
||||||
|
import * as Etebase from "etebase";
|
||||||
|
|
||||||
|
import * as store from "./store";
|
||||||
|
import { usePromiseMemo } from "./helpers";
|
||||||
|
|
||||||
|
export const credentialsSelector = createSelector(
|
||||||
|
(state: store.StoreState) => state.credentials2.storedSession,
|
||||||
|
(storedSession) => {
|
||||||
|
if (storedSession) {
|
||||||
|
return Etebase.Account.restore(storedSession);
|
||||||
|
} else {
|
||||||
|
return Promise.resolve(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export function useCredentials() {
|
||||||
|
const credentialsPromise = useSelector(credentialsSelector);
|
||||||
|
return usePromiseMemo(credentialsPromise, [credentialsPromise]);
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
import memoize from "memoizee";
|
||||||
|
|
||||||
|
import * as Etebase from "etebase";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
|
import { StoreState } from "./store";
|
||||||
|
import { CacheCollectionsData, CacheItems, CacheItemsData } from "./store/reducers";
|
||||||
|
import { usePromiseMemo } from "./helpers";
|
||||||
|
|
||||||
|
export const getCollections = memoize(async function (cachedCollections: CacheCollectionsData, etebase: Etebase.Account) {
|
||||||
|
const colMgr = getCollectionManager(etebase);
|
||||||
|
const ret: Etebase.Collection[] = [];
|
||||||
|
for (const cached of cachedCollections.values()) {
|
||||||
|
ret.push(await colMgr.cacheLoad(Etebase.fromBase64(cached)));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}, { length: 1 });
|
||||||
|
|
||||||
|
export const getCollectionsByType = memoize(async function (cachedCollections: CacheCollectionsData, colType: string, etebase: Etebase.Account) {
|
||||||
|
const collections = await getCollections(cachedCollections, etebase);
|
||||||
|
const ret: Etebase.Collection[] = [];
|
||||||
|
for (const col of collections) {
|
||||||
|
const meta = await col.getMeta();
|
||||||
|
if (meta.type === colType) {
|
||||||
|
ret.push(col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}, { length: 2 });
|
||||||
|
|
||||||
|
export const getItems = memoize(async function (cachedItems: CacheItems, itemMgr: Etebase.CollectionItemManager) {
|
||||||
|
const ret = new Map<string, Etebase.CollectionItem>();
|
||||||
|
for (const cached of cachedItems.values()) {
|
||||||
|
const item = await itemMgr.cacheLoad(Etebase.fromBase64(cached));
|
||||||
|
ret.set(item.uid, item);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}, { length: 1 });
|
||||||
|
|
||||||
|
export const getItemsByType = memoize(async function (cachedCollections: CacheCollectionsData, cachedItems: CacheItemsData, colType: string, etebase: Etebase.Account) {
|
||||||
|
const colMgr = getCollectionManager(etebase);
|
||||||
|
const collections = await getCollectionsByType(cachedCollections, colType, etebase);
|
||||||
|
const ret = new Map<string, Map<string, Etebase.CollectionItem>>();
|
||||||
|
for (const col of collections) {
|
||||||
|
const itemMgr = colMgr.getItemManager(col);
|
||||||
|
const cachedColItems = cachedItems.get(col.uid);
|
||||||
|
if (cachedColItems) {
|
||||||
|
const items = await getItems(cachedColItems, itemMgr);
|
||||||
|
ret.set(col.uid, items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}, { length: 3 });
|
||||||
|
|
||||||
|
export const getCollectionManager = memoize(function (etebase: Etebase.Account) {
|
||||||
|
return etebase.getCollectionManager();
|
||||||
|
});
|
||||||
|
|
||||||
|
// React specific stuff
|
||||||
|
export function useCollections(etebase: Etebase.Account, colType: string) {
|
||||||
|
const cachedCollections = useSelector((state: StoreState) => state.cache2.collections);
|
||||||
|
return usePromiseMemo(
|
||||||
|
getCollectionsByType(cachedCollections, colType, etebase),
|
||||||
|
[etebase, cachedCollections, colType]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useItems(etebase: Etebase.Account, colType: string) {
|
||||||
|
const cachedCollections = useSelector((state: StoreState) => state.cache2.collections);
|
||||||
|
const cachedItems = useSelector((state: StoreState) => state.cache2.items);
|
||||||
|
return usePromiseMemo(
|
||||||
|
getItemsByType(cachedCollections, cachedItems, colType, etebase),
|
||||||
|
[etebase, cachedCollections, cachedItems, colType]
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
// SPDX-FileCopyrightText: © 2017 EteSync Authors
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
// SPDX-FileCopyrightText: © 2017 EteSync Authors
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
// SPDX-FileCopyrightText: © 2019 EteSync Authors
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
|
||||||
|
import * as EteSync from "etesync";
|
||||||
|
|
||||||
|
export const deriveKey = EteSync.deriveKey;
|
Loading…
Reference in New Issue