Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/src/packages/frontend/account/store.ts
Views: 687
/*1* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.2* License: MS-RSL – see LICENSE.md for details3*/45import { List, Map } from "immutable";6import { reduce } from "lodash";7import { store as customizeStore } from "@cocalc/frontend/customize";8import { make_valid_name } from "@cocalc/util/misc";9import { Store } from "@cocalc/util/redux/Store";10import { get_total_upgrades } from "@cocalc/util/upgrades";11import { AccountState } from "./types";1213declare var DEBUG: boolean;1415// Define account store16export class AccountStore extends Store<AccountState> {17// User type18// - 'public' : user is not signed in at all, and not trying to sign in19// - 'signing_in' : user is currently waiting to see if sign-in attempt will succeed20// - 'signed_in' : user has successfully authenticated and has an id21constructor(name, redux) {22super(name, redux);23this.setup_selectors();24}2526get_user_type(): string {27return this.get("user_type");28}2930get_account_id(): string {31return this.get("account_id");32}3334selectors = {35is_anonymous: {36fn: () => {37return is_anonymous(38this.get("is_logged_in"),39this.get("email_address"),40this.get("passports"),41this.get("lti_id"),42);43},44dependencies: [45"email_address",46"passports",47"is_logged_in",48"lti_id",49] as const,50},51is_admin: {52fn: () => {53const groups = this.get("groups");54return !!groups && groups.includes("admin");55},56dependencies: ["groups"] as const,57},58};5960get_terminal_settings(): { [key: string]: any } | undefined {61return this.get("terminal") ? this.get("terminal").toJS() : undefined;62}6364get_editor_settings(): { [key: string]: any } | undefined {65return this.get("editor_settings")66? this.get("editor_settings").toJS()67: undefined;68}6970get_fullname(): string {71const first_name = this.get("first_name");72const last_name = this.get("last_name");73if (first_name == null && last_name == null) {74return "Anonymous";75} else if (first_name == undefined) {76return last_name ?? "";77} else if (last_name == undefined) {78return first_name ?? "";79} else {80return `${first_name} ${last_name}`;81}82}8384get_first_name(): string {85return this.get("first_name", "Anonymous");86}8788get_color(): string {89return this.getIn(90["profile", "color"],91this.get("account_id", "f00").slice(0, 6),92);93}9495get_username(): string {96return make_valid_name(this.get_fullname());97}9899get_email_address(): string | undefined {100return this.get("email_address");101}102103get_confirm_close(): string {104return this.getIn(["other_settings", "confirm_close"]);105}106107// Total upgrades this user is paying for (sum of all upgrades from subscriptions)108get_total_upgrades(): { [key: string]: number } | undefined {109const stripe_data = this.getIn([110"stripe_customer",111"subscriptions",112"data",113]);114// to fake having upgrades, type this in the console115// cc.redux.getStore('account').fake_upgrades = true116if (DEBUG && (this as any).fake_upgrades && !stripe_data) {117// fake debugging data118return get_total_upgrades({}, true);119}120return stripe_data && get_total_upgrades(stripe_data.toJS());121}122123hasLegacyUpgrades = () => {124return this.getIn(["stripe_customer", "subscriptions", "data"]) != null;125};126127// uses the total upgrades information to determine, if this is a paying member128// TODO: this is not used anywhere; but, if it was, it should also take into account129// being a license manager...130is_paying_member(): boolean {131const ups = this.get_total_upgrades();132return ups != null && reduce(ups, (a: number, b: number) => a + b, 0) > 0;133}134135get_page_size(): number {136return this.getIn(["other_settings", "page_size"], 500);137}138139isTourDone(tour: string): boolean {140const tours = this.get("tours");141if (!tours) return false;142return tours.includes(tour) || tours.includes("all");143}144}145146// A user is anonymous if they have not provided a way to sign147// in later (besides their cookie), i.e., if they have no148// passport strategies and have not provided an email address.149// In is_personal mode, user is never anonymous.150function is_anonymous(151is_logged_in: boolean,152email_address: string | undefined | null,153passports: Map<string, any> | undefined | null,154lti_id: List<string> | undefined | null,155): boolean {156if (!is_logged_in) {157return false;158}159if (email_address) {160return false;161}162if (passports != null && passports.size > 0) {163return false;164}165if (lti_id != null && lti_id.size > 0) {166return false;167}168if (customizeStore.get("is_personal")) {169return false;170}171return true;172}173174175