2020-02-03 12:03:07 +05:00
|
|
|
import Notes from "../collections/notes";
|
2020-04-13 12:46:29 +05:00
|
|
|
import Storage from "../database/storage";
|
2020-02-04 18:27:32 +05:00
|
|
|
import Notebooks from "../collections/notebooks";
|
2020-02-06 16:46:23 +05:00
|
|
|
import Trash from "../collections/trash";
|
2020-02-21 21:39:27 +05:00
|
|
|
import Tags from "../collections/tags";
|
2020-02-11 16:28:28 +05:00
|
|
|
import Sync from "./sync";
|
2020-03-07 12:29:55 +05:00
|
|
|
import Vault from "./vault";
|
2020-03-09 12:39:49 +05:00
|
|
|
import Lookup from "./lookup";
|
2020-03-19 11:30:05 +05:00
|
|
|
import Content from "../collections/content";
|
2020-09-13 13:24:24 +05:00
|
|
|
import Backup from "../database/backup";
|
2020-04-16 03:04:44 +05:00
|
|
|
import Conflicts from "./sync/conflicts";
|
2020-05-14 13:51:48 +05:00
|
|
|
import Session from "./session";
|
2020-09-19 11:46:36 +05:00
|
|
|
import Constants from "../utils/constants";
|
2021-01-23 10:48:21 +05:00
|
|
|
import { EV, EVENTS } from "../common";
|
2020-11-25 15:18:57 +05:00
|
|
|
import Settings from "./settings";
|
2020-12-05 15:26:54 +05:00
|
|
|
import Migrations from "./migrations";
|
2020-12-11 20:19:28 +05:00
|
|
|
import Outbox from "./outbox";
|
2020-12-16 12:06:25 +05:00
|
|
|
import UserManager from "./user-manager";
|
2021-01-05 14:07:02 +05:00
|
|
|
import http from "../utils/http";
|
2020-02-03 12:03:07 +05:00
|
|
|
|
2020-09-17 10:10:38 +05:00
|
|
|
/**
|
|
|
|
|
* @type {EventSource}
|
|
|
|
|
*/
|
|
|
|
|
var NNEventSource;
|
2020-02-11 13:12:47 +05:00
|
|
|
class Database {
|
2020-09-17 10:10:38 +05:00
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param {any} context
|
|
|
|
|
* @param {EventSource} eventsource
|
|
|
|
|
*/
|
|
|
|
|
constructor(context, eventsource) {
|
2020-04-13 12:46:29 +05:00
|
|
|
this.context = new Storage(context);
|
2020-09-17 10:10:38 +05:00
|
|
|
NNEventSource = eventsource;
|
2020-11-02 09:50:27 +05:00
|
|
|
this._syncTimeout = 0;
|
2020-02-03 12:03:07 +05:00
|
|
|
}
|
2020-04-15 23:25:53 +05:00
|
|
|
|
2020-05-14 13:56:39 +05:00
|
|
|
async _validate() {
|
2020-05-14 13:51:48 +05:00
|
|
|
if (!(await this.session.valid())) {
|
|
|
|
|
throw new Error(
|
|
|
|
|
"Your system clock is not setup correctly. Please adjust your date and time and then retry."
|
|
|
|
|
);
|
|
|
|
|
}
|
2020-05-14 13:56:39 +05:00
|
|
|
await this.session.set();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async init() {
|
2020-11-02 09:50:27 +05:00
|
|
|
EV.subscribeMulti(
|
2021-01-23 10:50:07 +05:00
|
|
|
[EVENTS.userLoggedIn, EVENTS.userLoggedOut, EVENTS.userFetched],
|
2020-08-24 11:25:09 +05:00
|
|
|
this._onUserStateChanged.bind(this)
|
|
|
|
|
);
|
2021-01-23 10:50:07 +05:00
|
|
|
EV.subscribe(EVENTS.databaseUpdated, this._onDBWrite.bind(this));
|
2020-08-24 11:25:09 +05:00
|
|
|
|
2020-05-14 15:07:49 +05:00
|
|
|
this.session = new Session(this.context);
|
2020-11-09 09:15:11 +05:00
|
|
|
await this._validate();
|
2020-05-14 13:51:48 +05:00
|
|
|
|
2020-12-16 12:06:25 +05:00
|
|
|
this.user = new UserManager(this);
|
2020-02-11 16:28:28 +05:00
|
|
|
this.syncer = new Sync(this);
|
2020-04-16 02:36:09 +05:00
|
|
|
this.vault = new Vault(this);
|
2020-04-04 13:29:33 +05:00
|
|
|
this.conflicts = new Conflicts(this);
|
2020-04-16 02:14:53 +05:00
|
|
|
this.lookup = new Lookup(this);
|
2020-09-13 13:24:24 +05:00
|
|
|
this.backup = new Backup(this);
|
2020-11-25 15:04:39 +05:00
|
|
|
this.settings = new Settings(this);
|
2020-12-05 15:26:54 +05:00
|
|
|
this.migrations = new Migrations(this);
|
2020-12-11 20:19:28 +05:00
|
|
|
this.outbox = new Outbox(this);
|
2020-04-16 02:14:53 +05:00
|
|
|
|
|
|
|
|
// collections
|
|
|
|
|
/** @type {Notes} */
|
2020-11-24 01:39:32 +05:00
|
|
|
this.notes = await Notes.new(this, "notes", true, true);
|
2020-04-16 02:14:53 +05:00
|
|
|
/** @type {Notebooks} */
|
2020-04-21 17:39:02 +05:00
|
|
|
this.notebooks = await Notebooks.new(this, "notebooks");
|
2020-04-16 02:14:53 +05:00
|
|
|
/** @type {Tags} */
|
|
|
|
|
this.tags = await Tags.new(this, "tags");
|
|
|
|
|
/** @type {Tags} */
|
|
|
|
|
this.colors = await Tags.new(this, "colors");
|
|
|
|
|
/** @type {Content} */
|
2020-11-04 10:17:37 +05:00
|
|
|
this.content = await Content.new(this, "content", false);
|
2020-09-07 09:45:31 +05:00
|
|
|
/** @type {Trash} */
|
|
|
|
|
this.trash = await Trash.new(this, "trash");
|
2020-08-25 09:08:55 +05:00
|
|
|
|
2020-11-25 15:04:39 +05:00
|
|
|
await this.settings.init();
|
2020-12-11 20:19:28 +05:00
|
|
|
await this.outbox.init();
|
2020-12-23 11:28:38 +05:00
|
|
|
await this.user.init();
|
2020-12-05 15:33:40 +05:00
|
|
|
|
2020-12-06 10:52:00 +05:00
|
|
|
await this.migrations.init();
|
2020-12-05 15:26:54 +05:00
|
|
|
await this.migrations.migrate();
|
2020-08-24 11:14:16 +05:00
|
|
|
}
|
|
|
|
|
|
2020-12-16 13:55:24 +05:00
|
|
|
async _onUserStateChanged() {
|
2020-09-17 10:10:38 +05:00
|
|
|
if (!NNEventSource) return;
|
2020-08-24 11:14:16 +05:00
|
|
|
if (this.evtSource) {
|
|
|
|
|
this.evtSource.close();
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-16 13:55:24 +05:00
|
|
|
let token = await this.user.tokenManager.getAccessToken();
|
2020-12-16 12:35:17 +05:00
|
|
|
this.evtSource = new NNEventSource(`${Constants.SSE_HOST}/sse`, {
|
2020-12-16 13:55:24 +05:00
|
|
|
headers: { Authorization: `Bearer ${token}` },
|
2020-08-24 11:14:16 +05:00
|
|
|
});
|
|
|
|
|
|
2020-08-24 11:25:09 +05:00
|
|
|
this.evtSource.onopen = function () {
|
2020-09-20 09:15:23 +05:00
|
|
|
console.log("SSE: opened channel successfully!");
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.evtSource.onerror = function (error) {
|
|
|
|
|
console.log("SSE: error:", error);
|
2020-08-24 11:25:09 +05:00
|
|
|
};
|
|
|
|
|
|
2020-08-24 11:14:16 +05:00
|
|
|
this.evtSource.onmessage = async (event) => {
|
2020-09-20 09:15:23 +05:00
|
|
|
try {
|
|
|
|
|
var { type, data } = JSON.parse(event.data);
|
2020-12-28 11:34:59 +05:00
|
|
|
data = JSON.parse(data);
|
2020-12-23 11:28:38 +05:00
|
|
|
console.log(type, data);
|
2020-09-20 09:15:23 +05:00
|
|
|
} catch (e) {
|
|
|
|
|
console.log("SSE: Unsupported message. Message = ", event.data);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-24 11:14:16 +05:00
|
|
|
switch (type) {
|
|
|
|
|
case "upgrade":
|
2021-01-22 22:08:56 +05:00
|
|
|
const user = await this.user.getUser();
|
|
|
|
|
user.subscription = data;
|
|
|
|
|
await this.user.setUser(user);
|
2021-01-23 10:48:21 +05:00
|
|
|
EV.publish(EVENTS.userSubscriptionUpdated, data);
|
2020-08-24 11:14:16 +05:00
|
|
|
break;
|
2020-12-10 15:29:12 +05:00
|
|
|
case "userDeleted":
|
2021-01-05 13:07:37 +05:00
|
|
|
await this.user.logout(false, "Account Deleted");
|
2020-12-10 14:53:58 +05:00
|
|
|
break;
|
2020-12-11 20:19:28 +05:00
|
|
|
case "userPasswordChanged":
|
2021-01-05 13:07:37 +05:00
|
|
|
await this.user.logout(true, "Password Changed");
|
2020-12-11 20:19:28 +05:00
|
|
|
break;
|
2020-12-23 11:28:38 +05:00
|
|
|
case "emailConfirmed":
|
|
|
|
|
const token = await this.context.read("token");
|
|
|
|
|
await this.user.tokenManager._refreshToken(token);
|
2021-01-05 13:07:37 +05:00
|
|
|
await this.user.fetchUser(true);
|
2021-01-23 10:48:21 +05:00
|
|
|
EV.publish(EVENTS.userEmailConfirmed);
|
2020-12-23 11:28:38 +05:00
|
|
|
break;
|
2020-08-24 11:14:16 +05:00
|
|
|
case "sync":
|
2020-08-24 13:07:16 +05:00
|
|
|
await this.syncer.eventMerge(data);
|
2020-08-24 11:14:16 +05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
};
|
2020-02-11 16:28:28 +05:00
|
|
|
}
|
|
|
|
|
|
2020-12-16 14:43:56 +05:00
|
|
|
async lastSynced() {
|
|
|
|
|
return this.context.read("lastSynced");
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-07 19:00:16 +05:00
|
|
|
_onDBWrite(item) {
|
|
|
|
|
if (item.remote) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-11-02 09:50:27 +05:00
|
|
|
clearTimeout(this._syncTimeout);
|
|
|
|
|
this._syncTimeout = setTimeout(() => {
|
2021-01-23 10:48:21 +05:00
|
|
|
EV.publish(EVENTS.databaseSyncRequested);
|
2020-12-07 15:53:33 +05:00
|
|
|
}, 15 * 1000);
|
2020-11-02 09:50:27 +05:00
|
|
|
}
|
|
|
|
|
|
2020-12-11 20:19:28 +05:00
|
|
|
sync(full = true, force = false) {
|
|
|
|
|
return this.syncer.start(full, force);
|
2020-02-03 12:03:07 +05:00
|
|
|
}
|
2020-09-19 11:36:37 +05:00
|
|
|
|
2020-12-16 12:35:17 +05:00
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param {{AUTH_HOST: string, API_HOST: string, SSE_HOST: string}} hosts
|
|
|
|
|
*/
|
|
|
|
|
host(hosts) {
|
2020-09-19 11:36:37 +05:00
|
|
|
if (process.env.NODE_ENV !== "production") {
|
2020-12-16 12:35:17 +05:00
|
|
|
Constants.AUTH_HOST = hosts.AUTH_HOST || Constants.AUTH_HOST;
|
|
|
|
|
Constants.API_HOST = hosts.API_HOST || Constants.API_HOST;
|
|
|
|
|
Constants.SSE_HOST = hosts.SSE_HOST || Constants.SSE_HOST;
|
2020-09-19 11:36:37 +05:00
|
|
|
}
|
|
|
|
|
}
|
2021-01-05 14:07:02 +05:00
|
|
|
|
|
|
|
|
version() {
|
|
|
|
|
return http.get(`${Constants.API_HOST}/version`);
|
|
|
|
|
}
|
2020-02-03 12:03:07 +05:00
|
|
|
}
|
|
|
|
|
|
2020-02-11 13:12:47 +05:00
|
|
|
export default Database;
|