ptn 0.3.2__py3-none-any.whl → 0.4.2__py3-none-any.whl
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.
- porterminal/_version.py +2 -2
- porterminal/application/services/management_service.py +28 -52
- porterminal/application/services/session_service.py +3 -11
- porterminal/application/services/terminal_service.py +97 -56
- porterminal/cli/args.py +39 -31
- porterminal/cli/display.py +18 -16
- porterminal/cli/script_discovery.py +112 -0
- porterminal/composition.py +2 -7
- porterminal/config.py +4 -2
- porterminal/domain/__init__.py +0 -9
- porterminal/domain/entities/output_buffer.py +56 -1
- porterminal/domain/entities/tab.py +11 -10
- porterminal/domain/services/__init__.py +0 -2
- porterminal/domain/values/__init__.py +0 -4
- porterminal/domain/values/environment_rules.py +3 -0
- porterminal/infrastructure/cloudflared.py +13 -11
- porterminal/infrastructure/config/shell_detector.py +86 -20
- porterminal/infrastructure/repositories/in_memory_session.py +1 -4
- porterminal/infrastructure/repositories/in_memory_tab.py +2 -10
- porterminal/pty/env.py +16 -78
- porterminal/pty/manager.py +6 -4
- porterminal/static/assets/app-DlWNJWFE.js +87 -0
- porterminal/static/assets/app-xPAM7YhQ.css +1 -0
- porterminal/static/index.html +2 -2
- porterminal/updater.py +13 -5
- {ptn-0.3.2.dist-info → ptn-0.4.2.dist-info}/METADATA +54 -16
- {ptn-0.3.2.dist-info → ptn-0.4.2.dist-info}/RECORD +30 -35
- porterminal/static/assets/app-BkHv5qu0.css +0 -32
- porterminal/static/assets/app-CaIGfw7i.js +0 -72
- porterminal/static/assets/app-D9ELFbEO.js +0 -72
- porterminal/static/assets/app-DF3nl_io.js +0 -72
- porterminal/static/assets/app-DQePboVd.css +0 -32
- porterminal/static/assets/app-DoBiVkTD.js +0 -72
- porterminal/static/assets/app-azbHOsRw.css +0 -32
- porterminal/static/assets/app-nMNFwMa6.css +0 -32
- {ptn-0.3.2.dist-info → ptn-0.4.2.dist-info}/WHEEL +0 -0
- {ptn-0.3.2.dist-info → ptn-0.4.2.dist-info}/entry_points.txt +0 -0
- {ptn-0.3.2.dist-info → ptn-0.4.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -44,16 +44,8 @@ class InMemoryTabRepository(TabRepository):
|
|
|
44
44
|
session_id = str(tab.session_id)
|
|
45
45
|
|
|
46
46
|
self._tabs[tab_id] = tab
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if user_id not in self._user_tabs:
|
|
50
|
-
self._user_tabs[user_id] = set()
|
|
51
|
-
self._user_tabs[user_id].add(tab_id)
|
|
52
|
-
|
|
53
|
-
# Index by session
|
|
54
|
-
if session_id not in self._session_tabs:
|
|
55
|
-
self._session_tabs[session_id] = set()
|
|
56
|
-
self._session_tabs[session_id].add(tab_id)
|
|
47
|
+
self._user_tabs.setdefault(user_id, set()).add(tab_id)
|
|
48
|
+
self._session_tabs.setdefault(session_id, set()).add(tab_id)
|
|
57
49
|
|
|
58
50
|
def update(self, tab: Tab) -> None:
|
|
59
51
|
"""Update an existing tab (name, last_accessed)."""
|
porterminal/pty/env.py
CHANGED
|
@@ -1,94 +1,32 @@
|
|
|
1
|
-
"""Environment variable sanitization for PTY processes.
|
|
1
|
+
"""Environment variable sanitization for PTY processes.
|
|
2
|
+
|
|
3
|
+
This module re-exports the environment rules from the domain layer
|
|
4
|
+
and provides the build_safe_environment() function for PTY spawning.
|
|
5
|
+
"""
|
|
2
6
|
|
|
3
7
|
import os
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
{
|
|
8
|
-
# System paths
|
|
9
|
-
"PATH",
|
|
10
|
-
"PATHEXT",
|
|
11
|
-
"SYSTEMROOT",
|
|
12
|
-
"WINDIR",
|
|
13
|
-
"TEMP",
|
|
14
|
-
"TMP",
|
|
15
|
-
"COMSPEC",
|
|
16
|
-
# User directories
|
|
17
|
-
"HOME",
|
|
18
|
-
"USERPROFILE",
|
|
19
|
-
"HOMEDRIVE",
|
|
20
|
-
"HOMEPATH",
|
|
21
|
-
"LOCALAPPDATA",
|
|
22
|
-
"APPDATA",
|
|
23
|
-
"PROGRAMFILES",
|
|
24
|
-
"PROGRAMFILES(X86)",
|
|
25
|
-
"COMMONPROGRAMFILES",
|
|
26
|
-
# System info
|
|
27
|
-
"COMPUTERNAME",
|
|
28
|
-
"USERNAME",
|
|
29
|
-
"USERDOMAIN",
|
|
30
|
-
"OS",
|
|
31
|
-
"PROCESSOR_ARCHITECTURE",
|
|
32
|
-
"NUMBER_OF_PROCESSORS",
|
|
33
|
-
# Terminal
|
|
34
|
-
"TERM",
|
|
35
|
-
# Locale settings for proper text rendering
|
|
36
|
-
"LANG",
|
|
37
|
-
"LC_ALL",
|
|
38
|
-
"LC_CTYPE",
|
|
39
|
-
}
|
|
9
|
+
from porterminal.domain.values.environment_rules import (
|
|
10
|
+
DEFAULT_BLOCKED_VARS as BLOCKED_ENV_VARS,
|
|
40
11
|
)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
BLOCKED_ENV_VARS: frozenset[str] = frozenset(
|
|
44
|
-
{
|
|
45
|
-
# AWS
|
|
46
|
-
"AWS_ACCESS_KEY_ID",
|
|
47
|
-
"AWS_SECRET_ACCESS_KEY",
|
|
48
|
-
"AWS_SESSION_TOKEN",
|
|
49
|
-
# Azure
|
|
50
|
-
"AZURE_CLIENT_SECRET",
|
|
51
|
-
"AZURE_CLIENT_ID",
|
|
52
|
-
# Git/GitHub/GitLab
|
|
53
|
-
"GH_TOKEN",
|
|
54
|
-
"GITHUB_TOKEN",
|
|
55
|
-
"GITLAB_TOKEN",
|
|
56
|
-
# Package managers
|
|
57
|
-
"NPM_TOKEN",
|
|
58
|
-
# AI APIs
|
|
59
|
-
"ANTHROPIC_API_KEY",
|
|
60
|
-
"OPENAI_API_KEY",
|
|
61
|
-
"GOOGLE_API_KEY",
|
|
62
|
-
# Payment
|
|
63
|
-
"STRIPE_SECRET_KEY",
|
|
64
|
-
# Database
|
|
65
|
-
"DATABASE_URL",
|
|
66
|
-
"DB_PASSWORD",
|
|
67
|
-
# Generic secrets
|
|
68
|
-
"SECRET_KEY",
|
|
69
|
-
"API_KEY",
|
|
70
|
-
"API_SECRET",
|
|
71
|
-
"PRIVATE_KEY",
|
|
72
|
-
}
|
|
12
|
+
from porterminal.domain.values.environment_rules import (
|
|
13
|
+
DEFAULT_SAFE_VARS as SAFE_ENV_VARS,
|
|
73
14
|
)
|
|
74
15
|
|
|
16
|
+
# Re-export for backward compatibility
|
|
17
|
+
__all__ = ["SAFE_ENV_VARS", "BLOCKED_ENV_VARS", "build_safe_environment"]
|
|
18
|
+
|
|
75
19
|
|
|
76
20
|
def build_safe_environment() -> dict[str, str]:
|
|
77
21
|
"""Build a sanitized environment for the PTY.
|
|
78
22
|
|
|
23
|
+
Uses allowlist approach - only SAFE_ENV_VARS are copied,
|
|
24
|
+
so BLOCKED_ENV_VARS can never be included.
|
|
25
|
+
|
|
79
26
|
Returns:
|
|
80
27
|
Dictionary of safe environment variables.
|
|
81
28
|
"""
|
|
82
|
-
safe_env:
|
|
83
|
-
|
|
84
|
-
# Copy only allowed variables
|
|
85
|
-
for var in SAFE_ENV_VARS:
|
|
86
|
-
if var in os.environ:
|
|
87
|
-
safe_env[var] = os.environ[var]
|
|
88
|
-
|
|
89
|
-
# Ensure blocked vars are not included (defense in depth)
|
|
90
|
-
for var in BLOCKED_ENV_VARS:
|
|
91
|
-
safe_env.pop(var, None)
|
|
29
|
+
safe_env = {var: os.environ[var] for var in SAFE_ENV_VARS if var in os.environ}
|
|
92
30
|
|
|
93
31
|
# Set custom variables for audit trail
|
|
94
32
|
safe_env["TERM"] = "xterm-256color"
|
porterminal/pty/manager.py
CHANGED
|
@@ -5,6 +5,8 @@ import shutil
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
from typing import TYPE_CHECKING
|
|
7
7
|
|
|
8
|
+
from porterminal.domain.values import MAX_COLS, MAX_ROWS, MIN_COLS, MIN_ROWS
|
|
9
|
+
|
|
8
10
|
from .env import build_safe_environment
|
|
9
11
|
from .protocol import PTYBackend
|
|
10
12
|
|
|
@@ -43,8 +45,8 @@ class SecurePTYManager:
|
|
|
43
45
|
"""
|
|
44
46
|
self._backend = backend
|
|
45
47
|
self.shell_config = shell_config
|
|
46
|
-
self.cols = max(
|
|
47
|
-
self.rows = max(
|
|
48
|
+
self.cols = max(MIN_COLS, min(cols, MAX_COLS))
|
|
49
|
+
self.rows = max(MIN_ROWS, min(rows, MAX_ROWS))
|
|
48
50
|
self.cwd = cwd
|
|
49
51
|
self._closed = False
|
|
50
52
|
|
|
@@ -133,8 +135,8 @@ class SecurePTYManager:
|
|
|
133
135
|
if self._closed:
|
|
134
136
|
return
|
|
135
137
|
|
|
136
|
-
cols = max(
|
|
137
|
-
rows = max(
|
|
138
|
+
cols = max(MIN_COLS, min(cols, MAX_COLS))
|
|
139
|
+
rows = max(MIN_ROWS, min(rows, MAX_ROWS))
|
|
138
140
|
|
|
139
141
|
try:
|
|
140
142
|
self._backend.resize(rows, cols)
|