CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/frontend/admin/users/password-reset.tsx
Views: 687
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 { Component, Rendered } from "@cocalc/frontend/app-framework";
7
import { Button } from "@cocalc/frontend/antd-bootstrap";
8
import { CopyToClipBoard, Icon, ErrorDisplay } from "@cocalc/frontend/components";
9
import { webapp_client } from "../../webapp-client";
10
import { appBasePath } from "@cocalc/frontend/customize/app-base-path";
11
12
interface Props {
13
email_address?: string;
14
}
15
16
interface State {
17
error?: string;
18
running: boolean;
19
link?: string;
20
}
21
22
export class PasswordReset extends Component<Props, State> {
23
mounted: boolean = true;
24
25
constructor(props: any) {
26
super(props);
27
this.state = { running: false };
28
}
29
30
componentWillUnmount(): void {
31
this.mounted = false;
32
}
33
34
async do_request(): Promise<void> {
35
if (!this.props.email_address) throw Error("bug");
36
this.setState({ running: true });
37
let link: string;
38
try {
39
link = await webapp_client.admin_client.admin_reset_password(
40
this.props.email_address
41
);
42
} catch (err) {
43
if (!this.mounted) return;
44
this.setState({ error: `${err}`, running: false });
45
return;
46
}
47
if (!this.mounted) return;
48
link = `${document.location.origin}${
49
appBasePath.length <= 1 ? "" : appBasePath
50
}${link}`;
51
this.setState({ link, running: false });
52
}
53
54
render_password_reset_button(): Rendered {
55
return (
56
<Button
57
disabled={this.state.running}
58
onClick={() => {
59
this.do_request();
60
}}
61
>
62
<Icon
63
name={this.state.running ? "sync" : "lock-open"}
64
spin={this.state.running}
65
/>{" "}
66
Request Password Reset Link...
67
</Button>
68
);
69
}
70
71
render_error(): Rendered {
72
if (!this.state.error) {
73
return;
74
}
75
return (
76
<ErrorDisplay
77
error={this.state.error}
78
onClose={() => {
79
this.setState({ error: undefined });
80
}}
81
/>
82
);
83
}
84
85
render_password_reset_link(): Rendered {
86
if (!this.state.link) return;
87
return (
88
<div>
89
<div style={{ marginTop: "20px" }}>
90
{" "}
91
Send this somehow to{" "}
92
<a
93
href={`mailto:${this.props.email_address}`}
94
target="_blank"
95
rel="noopener noreferrer"
96
>
97
{this.props.email_address}.
98
</a>
99
<br />
100
<CopyToClipBoard value={this.state.link} />
101
</div>
102
</div>
103
);
104
}
105
106
render(): Rendered {
107
if (!this.props.email_address) {
108
return (
109
<div>
110
User does not have an email address set, so password reset does not
111
make sense.
112
</div>
113
);
114
}
115
return (
116
<div>
117
<b>Password Reset:</b>
118
<br />
119
{this.render_error()}
120
{this.render_password_reset_button()}
121
{this.render_password_reset_link()}
122
<br />
123
<br />
124
</div>
125
);
126
}
127
}
128
129