Path: blob/master/src/packages/frontend/account/store.ts
1503 views
/*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";78import { store as customizeStore } from "@cocalc/frontend/customize";9import { make_valid_name } from "@cocalc/util/misc";10import { Store } from "@cocalc/util/redux/Store";11import { get_total_upgrades } from "@cocalc/util/upgrades";12import type { AccountState } from "./types";1314declare var DEBUG: boolean;1516// Define account store17export class AccountStore extends Store<AccountState> {18// User type19// - 'public' : user is not signed in at all, and not trying to sign in20// - 'signing_in' : user is currently waiting to see if sign-in attempt will succeed21// - 'signed_in' : user has successfully authenticated and has an id22constructor(name, redux) {23super(name, redux);24this.setup_selectors();25}2627get_user_type(): string {28return this.get("user_type");29}3031get_account_id(): string {32return this.get("account_id");33}3435selectors = {36is_anonymous: {37fn: () => {38return is_anonymous(39this.get("is_logged_in"),40this.get("email_address"),41this.get("passports"),42this.get("lti_id"),43);44},45dependencies: [46"email_address",47"passports",48"is_logged_in",49"lti_id",50] as const,51},52is_admin: {53fn: () => {54const groups = this.get("groups");55return !!groups && groups.includes("admin");56},57dependencies: ["groups"] as const,58},59};6061get_terminal_settings(): { [key: string]: any } | undefined {62return this.get("terminal") ? this.get("terminal").toJS() : undefined;63}6465get_editor_settings(): { [key: string]: any } | undefined {66return this.get("editor_settings")67? this.get("editor_settings").toJS()68: undefined;69}7071get_fullname(): string {72const first_name = this.get("first_name");73const last_name = this.get("last_name");74if (first_name == null && last_name == null) {75return "Anonymous";76} else if (first_name == undefined) {77return last_name ?? "";78} else if (last_name == undefined) {79return first_name ?? "";80} else {81return `${first_name} ${last_name}`;82}83}8485get_first_name(): string {86return this.get("first_name", "Anonymous");87}8889get_color(): string {90return this.getIn(91["profile", "color"],92this.get("account_id", "f00").slice(0, 6),93);94}9596get_username(): string {97return make_valid_name(this.get_fullname());98}99100get_email_address(): string | undefined {101return this.get("email_address");102}103104get_confirm_close(): string {105return this.getIn(["other_settings", "confirm_close"]);106}107108// Total upgrades this user is paying for (sum of all upgrades from subscriptions)109get_total_upgrades(): { [key: string]: number } | undefined {110const stripe_data = this.getIn([111"stripe_customer",112"subscriptions",113"data",114]);115// to fake having upgrades, type this in the console116// cc.redux.getStore('account').fake_upgrades = true117if (DEBUG && (this as any).fake_upgrades && !stripe_data) {118// fake debugging data119return get_total_upgrades({}, true);120}121return stripe_data && get_total_upgrades(stripe_data.toJS());122}123124hasLegacyUpgrades = () => {125return this.getIn(["stripe_customer", "subscriptions", "data"]) != null;126};127128// uses the total upgrades information to determine, if this is a paying member129// TODO: this is not used anywhere; but, if it was, it should also take into account130// being a license manager...131is_paying_member(): boolean {132const ups = this.get_total_upgrades();133return ups != null && reduce(ups, (a: number, b: number) => a + b, 0) > 0;134}135136get_page_size(): number {137return this.getIn(["other_settings", "page_size"], 500);138}139140isTourDone(tour: string): boolean {141const tours = this.get("tours");142if (!tours) return false;143return tours.includes(tour) || tours.includes("all");144}145146showSymbolBarLabels(): boolean {147return this.getIn(["other_settings", "show_symbol_bar_labels"], false);148}149}150151// A user is anonymous if they have not provided a way to sign152// in later (besides their cookie), i.e., if they have no153// passport strategies and have not provided an email address.154// In is_personal mode, user is never anonymous.155function is_anonymous(156is_logged_in: boolean,157email_address: string | undefined | null,158passports: Map<string, any> | undefined | null,159lti_id: List<string> | undefined | null,160): boolean {161if (!is_logged_in) {162return false;163}164if (email_address) {165return false;166}167if (passports != null && passports.size > 0) {168return false;169}170if (lti_id != null && lti_id.size > 0) {171return false;172}173if (customizeStore.get("is_personal")) {174return false;175}176return true;177}178179180