@push.rocks/smartdaemon 2.7.1 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.systemdservicedefinition.d.ts +14 -4
- package/dist_ts/classes.systemdservicedefinition.js +30 -3
- package/dist_ts/classes.systemdunit.d.ts +37 -7
- package/dist_ts/classes.systemdunit.js +106 -30
- package/dist_ts/classes.systemdunitfile.d.ts +13 -2
- package/dist_ts/classes.systemdunitfile.js +62 -35
- package/dist_ts/systemd.definition.d.ts +11 -1
- package/dist_ts/systemd.definition.js +18 -7
- package/dist_ts/systemd.userenvironment.d.ts +33 -0
- package/dist_ts/systemd.userenvironment.js +33 -0
- package/package.json +3 -3
- package/readme.md +106 -15
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.systemdservicedefinition.ts +46 -6
- package/ts/classes.systemdunit.ts +136 -35
- package/ts/classes.systemdunitfile.ts +76 -43
- package/ts/systemd.definition.ts +29 -7
- package/ts/systemd.userenvironment.ts +63 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as plugins from './smartdaemon.plugins.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The calling process's user-manager environment, captured once at construction so a unit file
|
|
5
|
+
* and the unit it drives read the same values. Nothing here is validated at capture: each value
|
|
6
|
+
* is checked by the operation that reads it, so a malformed variable that an operation never
|
|
7
|
+
* reads cannot stop that operation.
|
|
8
|
+
*/
|
|
9
|
+
export interface ISystemdUserEnvironment {
|
|
10
|
+
/** The account's home directory; absent when the calling uid has no passwd entry. */
|
|
11
|
+
readonly homeDirectory?: string;
|
|
12
|
+
/** A non-empty XDG_CONFIG_HOME. */
|
|
13
|
+
readonly configDirectory?: string;
|
|
14
|
+
/** A non-empty XDG_DATA_HOME. */
|
|
15
|
+
readonly dataDirectory?: string;
|
|
16
|
+
/** The explicit option, otherwise a non-empty XDG_RUNTIME_DIR. */
|
|
17
|
+
readonly runtimeDirectory?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** The environment every user-manager call passes to systemctl, once it has been admitted. */
|
|
21
|
+
export type TSystemdUserManagerEnvironment = ISystemdUserEnvironment & {
|
|
22
|
+
readonly homeDirectory: string;
|
|
23
|
+
readonly runtimeDirectory: string;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/** Absolute, normalized, bounded and printable; never the root itself or a trailing slash. */
|
|
27
|
+
export const isSafeDirectory = (value: unknown): value is string =>
|
|
28
|
+
typeof value === 'string' && value !== '/' && plugins.path.isAbsolute(value) &&
|
|
29
|
+
plugins.path.normalize(value) === value && !value.endsWith('/') &&
|
|
30
|
+
value.length <= 4000 && !/[\x00-\x1f\x7f]/.test(value);
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* An empty XDG variable counts as unset, as the XDG base directory specification defines. An
|
|
34
|
+
* explicit runtime directory option is never reinterpreted, so an empty option stays malformed.
|
|
35
|
+
*/
|
|
36
|
+
export const captureUserEnvironment = (
|
|
37
|
+
runtimeDirectoryOption: string | undefined,
|
|
38
|
+
): ISystemdUserEnvironment => {
|
|
39
|
+
let homeDirectory: string | undefined;
|
|
40
|
+
try {
|
|
41
|
+
homeDirectory = plugins.os.userInfo().homedir;
|
|
42
|
+
} catch {
|
|
43
|
+
// os.userInfo() throws for a uid without a passwd entry. The home directory is then absent,
|
|
44
|
+
// and every operation that reads it refuses with its own invalid_options code.
|
|
45
|
+
}
|
|
46
|
+
return Object.freeze({
|
|
47
|
+
homeDirectory,
|
|
48
|
+
configDirectory: process.env.XDG_CONFIG_HOME || undefined,
|
|
49
|
+
dataDirectory: process.env.XDG_DATA_HOME || undefined,
|
|
50
|
+
runtimeDirectory: runtimeDirectoryOption ?? (process.env.XDG_RUNTIME_DIR || undefined),
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Every call that reaches the user manager passes the runtime and home directories and any set
|
|
56
|
+
* XDG config/data roots to systemctl, so all of them must be well formed before the first call.
|
|
57
|
+
*/
|
|
58
|
+
export const isUserManagerEnvironment = (
|
|
59
|
+
environment: ISystemdUserEnvironment,
|
|
60
|
+
): environment is TSystemdUserManagerEnvironment =>
|
|
61
|
+
isSafeDirectory(environment.runtimeDirectory) && isSafeDirectory(environment.homeDirectory) &&
|
|
62
|
+
(environment.configDirectory === undefined || isSafeDirectory(environment.configDirectory)) &&
|
|
63
|
+
(environment.dataDirectory === undefined || isSafeDirectory(environment.dataDirectory));
|