magic-pocket-cli 0.2.2__tar.gz → 0.4.0__tar.gz
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.
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/PKG-INFO +2 -2
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/mediator.py +49 -1
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/aws/cloudformation.py +3 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/cloudfront.py +32 -1
- magic_pocket_cli-0.4.0/pocket_cli/templates/cloudformation/cf_function_api_host.js +9 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/templates/cloudformation/cloudfront.yaml +8 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pyproject.toml +2 -2
- magic_pocket_cli-0.2.2/pocket_cli/templates/cloudformation/cf_function_api_host.js +0 -5
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/.gitignore +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/__init__.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/cli/__init__.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/cli/aws_auth.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/cli/awscontainer_cli.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/cli/cloudfront_cli.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/cli/cloudfront_keys_cli.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/cli/cloudfront_waf_cli.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/cli/deploy_cli.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/cli/destroy_cli.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/cli/dsql_cli.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/cli/main_cli.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/cli/migrate_cli.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/cli/neon_cli.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/cli/permissions_cli.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/cli/rds_cli.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/cli/runtime_config_cli.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/cli/s3_cli.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/cli/status_cli.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/cli/tidb_cli.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/cli/vpc_cli.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/cli/waf_cli.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/django_cli.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/__init__.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/aws/__init__.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/aws/builders/__init__.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/aws/builders/codebuild.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/aws/builders/depot.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/aws/builders/docker.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/aws/builders/dockerignore.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/aws/ecr.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/aws/efs.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/aws/lambdahandler.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/aws/s3_utils.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/aws/state.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/awscontainer.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/cloudfront_acm.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/cloudfront_keys.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/cloudfront_waf.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/dsql.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/neon.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/rds.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/s3.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/tidb.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/upstash.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/vpc.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/templates/cloudformation/awscontainer.yaml +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/templates/cloudformation/cf_function_spa_auth.js +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/templates/cloudformation/cf_function_spa_fallback.js +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/templates/cloudformation/cloudfront_acm.yaml +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/templates/cloudformation/cloudfront_keys.yaml +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/templates/cloudformation/cloudfront_waf.yaml +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/templates/cloudformation/vpc.yaml +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/templates/init/django-dotenv.env +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/templates/init/django-settings.py +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/templates/init/pocket.Dockerfile +0 -0
- {magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/templates/init/pocket_simple.toml +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: magic-pocket-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: CLI and deploy tools for magic-pocket.
|
|
5
5
|
Requires-Python: >=3.10
|
|
6
6
|
Requires-Dist: awscrt>=0.19.0
|
|
7
7
|
Requires-Dist: click>=8.1.7
|
|
8
8
|
Requires-Dist: deepdiff>=6.7.1
|
|
9
9
|
Requires-Dist: jinja2>=3.1.3
|
|
10
|
-
Requires-Dist: magic-pocket>=0.
|
|
10
|
+
Requires-Dist: magic-pocket>=0.4.0
|
|
11
11
|
Requires-Dist: pathspec>=1.0.4
|
|
12
12
|
Requires-Dist: python-on-whales>=0.68.0
|
|
13
13
|
Requires-Dist: pyyaml>=6.0.1
|
|
@@ -60,6 +60,7 @@ class Mediator:
|
|
|
60
60
|
def ensure_pocket_managed_secrets(self):
|
|
61
61
|
self.create_pocket_managed_secrets(exists="ignore")
|
|
62
62
|
self._cleanup_orphaned_secrets()
|
|
63
|
+
self.verify_user_stored_secrets()
|
|
63
64
|
if self.context.awscontainer and self.context.awscontainer.secrets:
|
|
64
65
|
sc = self.context.awscontainer.secrets
|
|
65
66
|
if hasattr(sc, "pocket_store"):
|
|
@@ -69,6 +70,53 @@ class Mediator:
|
|
|
69
70
|
if hasattr(sc, "allowed_ssm_resources"):
|
|
70
71
|
del sc.allowed_ssm_resources
|
|
71
72
|
|
|
73
|
+
def verify_user_stored_secrets(self):
|
|
74
|
+
"""type 付き user secret (stored mode) が deploy 前に provision 済みか検証する。
|
|
75
|
+
|
|
76
|
+
computed (managed) と違い pocket は値を生成しないため、未 provision でも
|
|
77
|
+
deploy は通り runtime まで遅延して落ちる。それを避けるため deploy 時に store を
|
|
78
|
+
引いて存在を確認し、無ければ正準名を示して止める。管理 API は叩かない。
|
|
79
|
+
"""
|
|
80
|
+
if self.context.awscontainer is None:
|
|
81
|
+
return
|
|
82
|
+
if (sc := self.context.awscontainer.secrets) is None:
|
|
83
|
+
return
|
|
84
|
+
missing: list[str] = []
|
|
85
|
+
for key, spec in sc.user.items():
|
|
86
|
+
# type 付き = stored mode のみ対象。name は from_settings で導出済み。
|
|
87
|
+
if spec.type is None or spec.name is None:
|
|
88
|
+
continue
|
|
89
|
+
store = spec.store or sc.store
|
|
90
|
+
if not self._stored_secret_exists(spec.name, store, sc.region):
|
|
91
|
+
missing.append(
|
|
92
|
+
" - %s (type=%s, store=%s): %s"
|
|
93
|
+
% (key, spec.type, store, spec.name)
|
|
94
|
+
)
|
|
95
|
+
if missing:
|
|
96
|
+
raise RuntimeError(
|
|
97
|
+
"stored mode の user secret が見つかりません。"
|
|
98
|
+
"deploy 前に下記の secret を provision してください "
|
|
99
|
+
"(値は接続 URL):\n" + "\n".join(missing)
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
def _stored_secret_exists(self, name: str, store: str, region: str) -> bool:
|
|
103
|
+
import boto3
|
|
104
|
+
from botocore.exceptions import ClientError
|
|
105
|
+
|
|
106
|
+
try:
|
|
107
|
+
if store == "ssm":
|
|
108
|
+
boto3.client("ssm", region_name=region).get_parameter(Name=name)
|
|
109
|
+
else:
|
|
110
|
+
boto3.client("secretsmanager", region_name=region).describe_secret(
|
|
111
|
+
SecretId=name
|
|
112
|
+
)
|
|
113
|
+
return True
|
|
114
|
+
except ClientError as e:
|
|
115
|
+
code = e.response.get("Error", {}).get("Code", "")
|
|
116
|
+
if code in ("ParameterNotFound", "ResourceNotFoundException"):
|
|
117
|
+
return False
|
|
118
|
+
raise
|
|
119
|
+
|
|
72
120
|
def _cleanup_orphaned_secrets(self):
|
|
73
121
|
"""SSM/SM にあるが managed 定義にないシークレットを削除する"""
|
|
74
122
|
if self.context.awscontainer is None:
|
|
@@ -109,7 +157,7 @@ class Mediator:
|
|
|
109
157
|
return self._generate_rsa_pem()
|
|
110
158
|
elif spec.type == "cloudfront_signing_key":
|
|
111
159
|
return self._generate_rsa_pem()
|
|
112
|
-
elif spec.type
|
|
160
|
+
elif spec.type in ("spa_token_secret", "origin_verify_secret"):
|
|
113
161
|
return secrets.token_hex(32)
|
|
114
162
|
else:
|
|
115
163
|
raise RuntimeError("Unknown secret type: %s" % spec.type)
|
{magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/aws/cloudformation.py
RENAMED
|
@@ -358,8 +358,10 @@ class CloudFrontStack(Stack):
|
|
|
358
358
|
self,
|
|
359
359
|
context: CloudFrontContext,
|
|
360
360
|
token_secret_value: str = "",
|
|
361
|
+
origin_verify_secret_value: str = "",
|
|
361
362
|
):
|
|
362
363
|
self._token_secret_value = token_secret_value
|
|
364
|
+
self._origin_verify_secret_value = origin_verify_secret_value
|
|
363
365
|
super().__init__(context)
|
|
364
366
|
|
|
365
367
|
def get_client(self):
|
|
@@ -544,6 +546,7 @@ class CloudFrontStack(Stack):
|
|
|
544
546
|
deploy_hash_function_codes=deploy_hash_function_codes,
|
|
545
547
|
api_host_function_code=api_host_function_code,
|
|
546
548
|
has_token_kvs=self._has_token_kvs,
|
|
549
|
+
origin_verify_secret=self._origin_verify_secret_value,
|
|
547
550
|
**context_data,
|
|
548
551
|
)
|
|
549
552
|
return "\n".join(
|
|
@@ -49,6 +49,7 @@ class CloudFront:
|
|
|
49
49
|
self.s3_client = boto3.client("s3", region_name=context.s3_region)
|
|
50
50
|
self.cf_client = boto3.client("cloudfront")
|
|
51
51
|
self._token_secret_value: str = ""
|
|
52
|
+
self._origin_verify_secret_value: str = ""
|
|
52
53
|
|
|
53
54
|
@property
|
|
54
55
|
def description(self):
|
|
@@ -71,7 +72,9 @@ class CloudFront:
|
|
|
71
72
|
@property
|
|
72
73
|
def stack(self):
|
|
73
74
|
return CloudFrontStack(
|
|
74
|
-
self.context,
|
|
75
|
+
self.context,
|
|
76
|
+
token_secret_value=self._token_secret_value,
|
|
77
|
+
origin_verify_secret_value=self._origin_verify_secret_value,
|
|
75
78
|
)
|
|
76
79
|
|
|
77
80
|
def create(self, mediator: Mediator | None = None):
|
|
@@ -79,6 +82,7 @@ class CloudFront:
|
|
|
79
82
|
|
|
80
83
|
def update(self, mediator: Mediator | None = None):
|
|
81
84
|
self._prepare_token_secret(mediator)
|
|
85
|
+
self._prepare_origin_verify_secret(mediator)
|
|
82
86
|
self._ensure_redirect_from()
|
|
83
87
|
if not self.stack.exists:
|
|
84
88
|
self.stack.create()
|
|
@@ -136,6 +140,33 @@ class CloudFront:
|
|
|
136
140
|
% self.context.token_secret
|
|
137
141
|
)
|
|
138
142
|
|
|
143
|
+
def _prepare_origin_verify_secret(self, mediator: Mediator | None):
|
|
144
|
+
"""enable_origin_verify 時に origin verify secret の値を store から読む。
|
|
145
|
+
|
|
146
|
+
値は CFn テンプレートの OriginCustomHeaders に焼き込まれる
|
|
147
|
+
(token_secret の post-deploy KVS とは異なり、distribution config の一部
|
|
148
|
+
なので create/update 時点で必要)。managed secret なので AwsContainer
|
|
149
|
+
deploy 時に既に生成済み (get_resources は AwsContainer → CloudFront 順)。
|
|
150
|
+
"""
|
|
151
|
+
from pocket.context import ORIGIN_VERIFY_SECRET_KEY
|
|
152
|
+
|
|
153
|
+
if not self.context.enable_origin_verify:
|
|
154
|
+
return
|
|
155
|
+
if not mediator:
|
|
156
|
+
return
|
|
157
|
+
ac = mediator.context.awscontainer
|
|
158
|
+
if not ac or not ac.secrets:
|
|
159
|
+
return
|
|
160
|
+
secrets = ac.secrets.pocket_store.secrets
|
|
161
|
+
value = secrets.get(ORIGIN_VERIFY_SECRET_KEY)
|
|
162
|
+
if isinstance(value, str):
|
|
163
|
+
self._origin_verify_secret_value = value
|
|
164
|
+
else:
|
|
165
|
+
echo.warning(
|
|
166
|
+
"origin verify secret '%s' が managed secrets に見つかりません"
|
|
167
|
+
% ORIGIN_VERIFY_SECRET_KEY
|
|
168
|
+
)
|
|
169
|
+
|
|
139
170
|
def _write_token_secret_to_kvs(self):
|
|
140
171
|
if not self._token_secret_value:
|
|
141
172
|
return
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
function handler(event) {
|
|
2
|
+
var request = event.request;
|
|
3
|
+
request.headers['x-forwarded-host'] = { value: request.headers.host.value };
|
|
4
|
+
// event.viewer.ip は CloudFront が TCP 接続から取得する viewer IP で詐称不可。
|
|
5
|
+
// viewer が同名 header を送っても上書きするため、origin は真の client IP を
|
|
6
|
+
// 信頼できる。OriginVerifyMiddleware が REMOTE_ADDR に正規化する。
|
|
7
|
+
request.headers['x-pocket-viewer-ip'] = { value: event.viewer.ip };
|
|
8
|
+
return request;
|
|
9
|
+
}
|
|
@@ -129,6 +129,14 @@ Resources:
|
|
|
129
129
|
CustomOriginConfig:
|
|
130
130
|
OriginProtocolPolicy: https-only
|
|
131
131
|
HTTPSPort: 443
|
|
132
|
+
# {% if origin_verify_secret %}
|
|
133
|
+
# CloudFront → origin にのみ付与する secret header。viewer が同名 header
|
|
134
|
+
# を送っても CloudFront が上書きするため詐称不可。origin (API GW / Lambda)
|
|
135
|
+
# 直叩きを検出するために OriginVerifyMiddleware が同値を検証する。
|
|
136
|
+
OriginCustomHeaders:
|
|
137
|
+
- HeaderName: "X-Pocket-Origin-Verify"
|
|
138
|
+
HeaderValue: "{{ origin_verify_secret }}"
|
|
139
|
+
# {% endif %}
|
|
132
140
|
# {% endfor %}
|
|
133
141
|
# {% if managed_asset_files %}
|
|
134
142
|
- Id: "{{ resource_prefix }}pocket-managed"
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "magic-pocket-cli"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.4.0"
|
|
4
4
|
description = "CLI and deploy tools for magic-pocket."
|
|
5
5
|
requires-python = ">=3.10"
|
|
6
6
|
dependencies = [
|
|
7
|
-
"magic-pocket>=0.
|
|
7
|
+
"magic-pocket>=0.4.0",
|
|
8
8
|
"click>=8.1.7",
|
|
9
9
|
"jinja2>=3.1.3",
|
|
10
10
|
"python-on-whales>=0.68.0",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/aws/builders/__init__.py
RENAMED
|
File without changes
|
{magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/aws/builders/codebuild.py
RENAMED
|
File without changes
|
{magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/aws/builders/depot.py
RENAMED
|
File without changes
|
{magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/aws/builders/docker.py
RENAMED
|
File without changes
|
{magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/resources/aws/builders/dockerignore.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/templates/cloudformation/vpc.yaml
RENAMED
|
File without changes
|
{magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/templates/init/django-dotenv.env
RENAMED
|
File without changes
|
{magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/templates/init/django-settings.py
RENAMED
|
File without changes
|
{magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/templates/init/pocket.Dockerfile
RENAMED
|
File without changes
|
{magic_pocket_cli-0.2.2 → magic_pocket_cli-0.4.0}/pocket_cli/templates/init/pocket_simple.toml
RENAMED
|
File without changes
|