ui/server/src/workspace
The workspace boundary.
Cockpit server, next. Source: ui/server/src/workspace.mjs.
Classes#
WorkspaceError#
Defined in: ui/server/src/workspace.mjs:30
Extends#
Error
Constructors#
Constructor
new WorkspaceError(
status,code,message):WorkspaceError
Defined in: ui/server/src/workspace.mjs:32
Parameters
status
number
code
string
message
string
Returns
Overrides
Error.constructor
Properties#
code
code:
string
Defined in: ui/server/src/workspace.mjs:36
name
name:
string
Defined in: ui/server/src/workspace.mjs:34
Inherited from
Error.name
status
status:
number
Defined in: ui/server/src/workspace.mjs:35
Variables#
MAX_LOGIN_LENGTH#
constMAX_LOGIN_LENGTH:64=64
Defined in: ui/server/src/workspace.mjs:189
MAX_PATH_LENGTH#
constMAX_PATH_LENGTH:4096=4096
Defined in: ui/server/src/workspace.mjs:28
Functions#
baseWorkspaceRoot()#
baseWorkspaceRoot(
__namedParameters?):any
Defined in: ui/server/src/workspace.mjs:180
The base workspace root for this server process (resolved from the environment on first use). Pass
{ authRequired: true } at startup to apply the hosted-mode rules (see resolveWorkspaceRoot).
Parameters#
__namedParameters?
authRequired?
boolean = false
Returns#
any
contain()#
contain(
root,requested,opts?):string
Defined in: ui/server/src/workspace.mjs:142
Resolve requested to a real path inside root, or throw a WorkspaceError.
Parameters#
root
string
the realpath'd workspace root (from resolveWorkspaceRoot)
requested
unknown
a client-supplied path (absolute, or relative to base)
opts?
base?
string = root
mustBeDir?
boolean = false
mustBeFile?
boolean = false
mustExist?
boolean = true
Returns#
string
the real absolute path (for a not-yet-existing path: real ancestor + the remainder)
containInWorkspace()#
containInWorkspace(
requested,opts):string
Defined in: ui/server/src/workspace.mjs:267
contain() against the current workspace root.
Parameters#
requested
any
opts
any
Returns#
string
containOrNull()#
containOrNull(
root,requested,opts):string
Defined in: ui/server/src/workspace.mjs:160
Non-throwing form of contain: the real path, or null.
Parameters#
root
any
requested
any
opts
any
Returns#
string
currentLogin()#
currentLogin():
any
Defined in: ui/server/src/workspace.mjs:257
The signed-in login (validated, lowercased) of the current request, or '' when there is no session (auth off).
Returns#
any
isInside()#
isInside(
root,target):boolean
Defined in: packages/core/fs.mjs:51
True when target is root or nested under it. Both must already be real, absolute paths
(callers resolve symlinks first when the containment check is security-sensitive).
Parameters#
root
string
target
string
Returns#
boolean
normalizeLogin()#
normalizeLogin(
login):string
Defined in: ui/server/src/workspace.mjs:195
The one place a login is validated as a single safe path segment: lowercased, bounded, [a-z0-9_-].
Anything that builds a path from a login (workspace directory, per-user state file) goes through this.
Parameters#
login
any
Returns#
string
relativeToWorkspace()#
relativeToWorkspace(
root,target):any
Defined in: ui/server/src/workspace.mjs:170
Workspace-relative display form ("" for the root itself, otherwise "a/b"), always with forward slashes.
Parameters#
root
any
target
any
Returns#
any
resetWorkspaceRootForTests()#
resetWorkspaceRootForTests():
void
Defined in: ui/server/src/workspace.mjs:262
Test seam: forget the cached root so the next workspaceRoot() re-reads the environment.
Returns#
void
resolveWorkspaceRoot()#
resolveWorkspaceRoot(
env?,__namedParameters?):any
Defined in: ui/server/src/workspace.mjs:63
Resolve (and create if missing) the workspace root. Throws a plain Error on a relative or unusable value:
the server must refuse to start rather than run with a boundary it cannot establish.
With authRequired (a hosted, multi-user Cockpit) the root must be configured explicitly (no $HOME/workspace
default) and must not be, sit inside, or contain the Construct checkout or the process cwd, so a signed-in user
can never reach the server's own code, config or state.
Parameters#
env?
any = process.env
__namedParameters?
authRequired?
boolean = false
checkout?
any = CHECKOUT_ROOT
cwd?
any = ...
home?
any = ...
Returns#
any
runInUserWorkspace()#
runInUserWorkspace(
login,fn):any
Defined in: ui/server/src/workspace.mjs:231
Run fn with workspaceRoot() scoped to login's private directory (throws a 403 WorkspaceError for an unusable login).
Parameters#
login
any
fn
any
Returns#
any
userWorkspaceDir()#
userWorkspaceDir(
base,login):string
Defined in: ui/server/src/workspace.mjs:209
The private directory of login under the base root: created on first use with mode 0700, realpath'd and
confirmed strictly inside base (a <base>/<login> that is a symlink leading out is refused).
Parameters#
base
string
the realpath'd base root
login
unknown
a session login
Returns#
string
the real absolute path of the user's directory
userWorkspaceMiddleware()#
userWorkspaceMiddleware(
req,res,next):any
Defined in: ui/server/src/workspace.mjs:238
Express middleware: mount ONCE, right after the session gate. With req.session.login the rest of the request
(and everything it awaits) sees workspaceRoot() as that user's directory; with no session (auth off) it is a no-op.
Parameters#
req
any
res
any
next
any
Returns#
any
workspaceRoot()#
workspaceRoot():
any
Defined in: ui/server/src/workspace.mjs:252
The workspace root for the current request: the signed-in user's directory, else the base root.
Returns#
any