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/compute/auth-token.tsx
Views: 687
1
import { useEffect, useState } from "react";
2
import generateVouchers from "@cocalc/util/vouchers";
3
import { Button, Input, Popconfirm, Spin } from "antd";
4
import { Icon } from "@cocalc/frontend/components/icon";
5
import { PROXY_AUTH_TOKEN_FILE } from "@cocalc/util/compute/constants";
6
import { writeTextFileToComputeServer } from "./project";
7
import ShowError from "@cocalc/frontend/components/error";
8
9
function createToken() {
10
return generateVouchers({ count: 1, length: 16 })[0];
11
}
12
13
export default function AuthToken({
14
id,
15
project_id,
16
setConfig,
17
configuration,
18
state,
19
IMAGES,
20
}) {
21
const [error, setError] = useState<string>("");
22
const [saving, setSaving] = useState<boolean>(false);
23
const { proxy, authToken } = IMAGES?.[configuration.image] ?? {};
24
const noAuthToken = proxy === false && !authToken;
25
26
const updateAuthToken = async () => {
27
const authToken = createToken();
28
try {
29
setSaving(true);
30
setError("");
31
await setConfig({ authToken });
32
if (id && state == "running") {
33
// also attempt to write it directly to the file system, which updates
34
// the proxy server in realtime to use the new token.
35
await writeAuthToken({
36
compute_server_id: id,
37
project_id,
38
authToken,
39
});
40
}
41
} catch (err) {
42
setError(`${err}`);
43
} finally {
44
setSaving(false);
45
}
46
};
47
useEffect(() => {
48
if (noAuthToken) {
49
return;
50
}
51
// create token if it is not set but required
52
if (configuration.authToken == null) {
53
updateAuthToken();
54
}
55
}, [noAuthToken, configuration.authToken]);
56
57
if (noAuthToken) {
58
// image that doesn't use authToken in any ways
59
return null;
60
}
61
62
return (
63
<div style={{ color: "#666" }}>
64
<div style={{ marginTop: "15px", display: "flex" }}>
65
<div style={{ margin: "auto 30px auto 0" }}>
66
<b>Auth Token:</b>
67
</div>
68
<ShowError
69
error={error}
70
setError={setError}
71
style={{ margin: "15px 0" }}
72
/>
73
<Input.Password
74
style={{ width: "200px" }}
75
readOnly
76
value={configuration.authToken ?? ""}
77
/>
78
<Popconfirm
79
onConfirm={updateAuthToken}
80
okText="Change token"
81
title={"Change auth token?"}
82
description={
83
<div style={{ width: "400px" }}>
84
<b>
85
WARNING: Changing the auth token will prevent people who you
86
shared the old token with from using the site.
87
</b>
88
</div>
89
}
90
>
91
<Button
92
style={{ marginLeft: "30px" }}
93
disabled={
94
saving ||
95
(authToken &&
96
state != "deprovisioned" &&
97
state != "off") /* will get rid of soon */
98
}
99
>
100
<Icon name="refresh" />
101
Randomize...
102
{saving && <Spin />}
103
</Button>
104
</Popconfirm>
105
</div>
106
</div>
107
);
108
}
109
110
async function writeAuthToken({ authToken, project_id, compute_server_id }) {
111
await writeTextFileToComputeServer({
112
value: authToken,
113
project_id,
114
compute_server_id,
115
sudo: true,
116
path: PROXY_AUTH_TOKEN_FILE,
117
});
118
}
119
120