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/backend/misc.ts
Views: 687
1
import { createHash } from "crypto";
2
import { is_valid_uuid_string } from "@cocalc/util/misc";
3
4
/*
5
getUid
6
7
We take the sha-512 hash of the project_id uuid just to make it harder to force
8
a collision. Thus even if a user could somehow generate an account id of their
9
choosing, this wouldn't help them get the same uid as another user. We use
10
this approach only a single Linux system, so are only likely to have a handful
11
of accounts anyways, and users are mostly trusted.
12
13
- 2^31-1=max uid which works with FUSE and node (and Linux, which goes up to 2^32-2).
14
- 2^29 was the biggest that seemed to work with Docker on my crostini pixelbook,
15
so shrinking to that.
16
- it is always at least 65537 to avoid conflicts with existing users.
17
*/
18
export function getUid(project_id: string): number {
19
if (!is_valid_uuid_string(project_id)) {
20
throw Error(`project_id (=${project_id}) must be a valid v4 uuid`);
21
}
22
23
const sha512sum = createHash("sha512");
24
let n = parseInt(sha512sum.update(project_id).digest("hex").slice(0, 8), 16); // up to 2^32
25
n = Math.floor(n / 8); // floor division
26
if (n > 65537) {
27
return n;
28
} else {
29
return n + 65537;
30
} // 65534 used by linux for user sync, etc.
31
}
32
33
import { re_url, to_human_list } from "@cocalc/util/misc";
34
export { contains_url } from "@cocalc/util/misc";
35
36
// returns undefined if ok, otherwise an error message.
37
// TODO: this should probably be called "validate_username". It's only used in @cocalc/database right now
38
// as a backend double check on the first and last name when creating accounts in the database.
39
export function is_valid_username(str: string): string | undefined {
40
const name = str.toLowerCase();
41
42
const found = name.match(re_url);
43
if (found) {
44
return `URLs are not allowed. Found ${to_human_list(found)}`;
45
}
46
47
if (name.indexOf("mailto:") != -1 && name.indexOf("@") != -1) {
48
return "email addresses are not allowed";
49
}
50
51
return;
52
}
53
54
// integer from process environment variable, with fallback
55
export function process_env_int(name: string, fallback: number): number {
56
const val = process.env[name];
57
if (val == null) return fallback;
58
try {
59
return parseInt(val);
60
} catch {
61
return fallback;
62
}
63
}
64
65
export function envForSpawn() {
66
const env = { ...process.env };
67
for (const name of ["DEBUG", "DEBUG_CONSOLE", "NODE_ENV", "DEBUG_FILE"]) {
68
delete env[name];
69
}
70
return env;
71
}
72
73