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/next/pages/api/v2/projects/copy-url.ts
Views: 687
1
/*
2
API endpoint to copy from a URL on the internet to a project.
3
4
This requires the user to be signed in with appropriate access to the project.
5
6
If project doesn't have network access, we stop the project, start it with
7
network access, get the content, then restart the project without network access.
8
*/
9
10
import getAccountId from "lib/account/get-account";
11
import { isValidUUID } from "@cocalc/util/misc";
12
import isCollaborator from "@cocalc/server/projects/is-collaborator";
13
import getParams from "lib/api/get-params";
14
import call from "@cocalc/server/projects/connection/call";
15
import getProxiedPublicPathInfo from "lib/share/proxy/get-proxied-public-path-info";
16
17
export default async function handle(req, res) {
18
const params = getParams(req);
19
const error = checkParams(params);
20
if (error) {
21
res.json({ error });
22
return;
23
}
24
const {
25
project_id,
26
url, // the supported schema is as in next/lib/share/proxy/get-public-path.ts).
27
path, // where to write the contents of the url
28
} = params;
29
30
try {
31
const account_id = await getAccountId(req);
32
if (!account_id) {
33
throw Error("must be signed in");
34
}
35
if (!(await isCollaborator({ account_id, project_id }))) {
36
throw Error("must be a collaborator on target project");
37
}
38
const info = await getProxiedPublicPathInfo(url);
39
if (info.contents?.content == null) {
40
throw Error(
41
"copying of directories (e.g., full GitHub repos) is not implemented; copy an individual file instead",
42
);
43
}
44
const i = url.lastIndexOf("/");
45
const filename = url.slice(i + 1);
46
const mesg = {
47
event: "write_text_file_to_project",
48
path: path ? path : filename,
49
content: info.contents.content,
50
};
51
const response = await call({ project_id, mesg });
52
res.json({ response });
53
} catch (err) {
54
res.json({ error: `${err.message}` });
55
}
56
}
57
58
function checkParams(obj: any): string | undefined {
59
if (!obj.url) return "url must be specified";
60
if (!isValidUUID(obj.project_id)) return "project_id must be a valid uuid";
61
}
62
63