Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/account/init.ts
1503 views
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
import { deep_copy } from "@cocalc/util/misc";
7
import { SCHEMA } from "@cocalc/util/schema";
8
import { webapp_client } from "../webapp-client";
9
import { AccountActions } from "./actions";
10
import { AccountStore } from "./store";
11
import { AccountTable } from "./table";
12
import { init_dark_mode } from "./dark-mode";
13
import { reset_password_key } from "../client/password-reset";
14
import { hasRememberMe } from "@cocalc/frontend/misc/remember-me";
15
import { appBasePath } from "@cocalc/frontend/customize/app-base-path";
16
import { once } from "@cocalc/util/async-utils";
17
18
export function init(redux) {
19
// Register account store
20
// Use the database defaults for all account info until this gets set after they login
21
const init = deep_copy(SCHEMA.accounts.user_query?.get?.fields) ?? {};
22
// ... except for show_global_info2 (null or a timestamp)
23
// REGISTER and STRATEGIES are injected in app.html via the /customize endpoint -- do not delete them!
24
init.token = global["REGISTER"];
25
init.strategies = global["STRATEGIES"];
26
init.other_settings.show_global_info2 = "loading"; // indicates there is no data yet
27
init.editor_settings.physical_keyboard = "NO_DATA"; // indicator that there is no data
28
init.user_type = hasRememberMe(appBasePath) ? "signing_in" : "public"; // default
29
const store = redux.createStore("account", AccountStore, init);
30
const actions = redux.createActions("account", AccountActions);
31
32
actions._init(store);
33
init_dark_mode(store);
34
35
redux.createTable("account", AccountTable);
36
redux.getTable("account")._table.on("error", (tableError) => {
37
actions.setState({ tableError });
38
});
39
redux.getTable("account")._table.on("clear-error", () => {
40
actions.setState({ tableError: undefined });
41
});
42
43
// Password reset
44
actions.setState({ reset_key: reset_password_key() });
45
46
// Login status
47
webapp_client.on("signed_in", async (mesg) => {
48
if (mesg?.api_key) {
49
// wait for sign in to finish and cookie to get set, then redirect
50
setTimeout(() => {
51
window.location.href = `https://authenticated?api_key=${mesg.api_key}`;
52
}, 2000);
53
}
54
const table = redux.getTable("account")._table;
55
if (table != "connected") {
56
// not fully signed in until the account table is connected, so that we know
57
// email address, etc. If we don't set this, the UI thinks the user is anonymous
58
// for a second, which is disconcerting.
59
await once(table, "connected");
60
}
61
redux.getActions("account").set_user_type("signed_in");
62
});
63
64
webapp_client.on("signed_out", () =>
65
redux.getActions("account").set_user_type("public"),
66
);
67
68
webapp_client.on("remember_me_failed", () =>
69
redux.getActions("account").set_user_type("public"),
70
);
71
72
// Autosave interval
73
let _autosave_interval: NodeJS.Timeout | undefined = undefined;
74
const init_autosave = function (autosave) {
75
if (_autosave_interval) {
76
// This function can safely be called again to *adjust* the
77
// autosave interval, in case user changes the settings.
78
clearInterval(_autosave_interval);
79
_autosave_interval = undefined;
80
}
81
82
// Use the most recent autosave value.
83
if (autosave) {
84
const save_all_files = function () {
85
if (webapp_client.is_connected()) {
86
redux.getActions("projects")?.save_all_files();
87
}
88
};
89
_autosave_interval = setInterval(save_all_files, autosave * 1000);
90
}
91
};
92
93
let _last_autosave_interval_s = undefined;
94
store.on("change", function () {
95
const interval_s = store.get("autosave");
96
if (interval_s !== _last_autosave_interval_s) {
97
_last_autosave_interval_s = interval_s;
98
init_autosave(interval_s);
99
}
100
});
101
102
// Standby timeout
103
let last_set_standby_timeout_m = undefined;
104
store.on("change", function () {
105
// NOTE: we call this on any change to account settings, which is maybe too extreme.
106
const x = store.getIn(["other_settings", "standby_timeout_m"]);
107
if (last_set_standby_timeout_m !== x) {
108
last_set_standby_timeout_m = x;
109
webapp_client.idle_client.set_standby_timeout_m(x);
110
}
111
});
112
}
113
114