@cicore/cli 1.0.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/bin/ci.js +13 -0
- package/dist/commands/addon/api-actions.d.ts +45 -0
- package/dist/commands/addon/api-actions.d.ts.map +1 -0
- package/dist/commands/addon/api-actions.js +281 -0
- package/dist/commands/addon/api-actions.js.map +1 -0
- package/dist/commands/addon/build.d.ts +11 -0
- package/dist/commands/addon/build.d.ts.map +1 -0
- package/dist/commands/addon/build.js +182 -0
- package/dist/commands/addon/build.js.map +1 -0
- package/dist/commands/addon/create.d.ts +11 -0
- package/dist/commands/addon/create.d.ts.map +1 -0
- package/dist/commands/addon/create.js +1186 -0
- package/dist/commands/addon/create.js.map +1 -0
- package/dist/commands/addon/delete.d.ts +13 -0
- package/dist/commands/addon/delete.d.ts.map +1 -0
- package/dist/commands/addon/delete.js +83 -0
- package/dist/commands/addon/delete.js.map +1 -0
- package/dist/commands/addon/deploy.d.ts +27 -0
- package/dist/commands/addon/deploy.d.ts.map +1 -0
- package/dist/commands/addon/deploy.js +459 -0
- package/dist/commands/addon/deploy.js.map +1 -0
- package/dist/commands/addon/dev-deploy.d.ts +31 -0
- package/dist/commands/addon/dev-deploy.d.ts.map +1 -0
- package/dist/commands/addon/dev-deploy.js +128 -0
- package/dist/commands/addon/dev-deploy.js.map +1 -0
- package/dist/commands/addon/dev.d.ts +36 -0
- package/dist/commands/addon/dev.d.ts.map +1 -0
- package/dist/commands/addon/dev.js +323 -0
- package/dist/commands/addon/dev.js.map +1 -0
- package/dist/commands/addon/extract-classes.d.ts +23 -0
- package/dist/commands/addon/extract-classes.d.ts.map +1 -0
- package/dist/commands/addon/extract-classes.js +281 -0
- package/dist/commands/addon/extract-classes.js.map +1 -0
- package/dist/commands/addon/generate-safelist.d.ts +24 -0
- package/dist/commands/addon/generate-safelist.d.ts.map +1 -0
- package/dist/commands/addon/generate-safelist.js +276 -0
- package/dist/commands/addon/generate-safelist.js.map +1 -0
- package/dist/commands/addon/index.d.ts +19 -0
- package/dist/commands/addon/index.d.ts.map +1 -0
- package/dist/commands/addon/index.js +296 -0
- package/dist/commands/addon/index.js.map +1 -0
- package/dist/commands/addon/init-repo.d.ts +25 -0
- package/dist/commands/addon/init-repo.d.ts.map +1 -0
- package/dist/commands/addon/init-repo.js +171 -0
- package/dist/commands/addon/init-repo.js.map +1 -0
- package/dist/commands/addon/install.d.ts +23 -0
- package/dist/commands/addon/install.d.ts.map +1 -0
- package/dist/commands/addon/install.js +84 -0
- package/dist/commands/addon/install.js.map +1 -0
- package/dist/commands/addon/list.d.ts +10 -0
- package/dist/commands/addon/list.d.ts.map +1 -0
- package/dist/commands/addon/list.js +102 -0
- package/dist/commands/addon/list.js.map +1 -0
- package/dist/commands/addon/manifest-refresh.d.ts +17 -0
- package/dist/commands/addon/manifest-refresh.d.ts.map +1 -0
- package/dist/commands/addon/manifest-refresh.js +48 -0
- package/dist/commands/addon/manifest-refresh.js.map +1 -0
- package/dist/commands/addon/migrate.d.ts +40 -0
- package/dist/commands/addon/migrate.d.ts.map +1 -0
- package/dist/commands/addon/migrate.js +236 -0
- package/dist/commands/addon/migrate.js.map +1 -0
- package/dist/commands/addon/publish.d.ts +33 -0
- package/dist/commands/addon/publish.d.ts.map +1 -0
- package/dist/commands/addon/publish.js +236 -0
- package/dist/commands/addon/publish.js.map +1 -0
- package/dist/commands/addon/scaffold-quality.d.ts +21 -0
- package/dist/commands/addon/scaffold-quality.d.ts.map +1 -0
- package/dist/commands/addon/scaffold-quality.js +90 -0
- package/dist/commands/addon/scaffold-quality.js.map +1 -0
- package/dist/commands/addon/sign.d.ts +9 -0
- package/dist/commands/addon/sign.d.ts.map +1 -0
- package/dist/commands/addon/sign.js +83 -0
- package/dist/commands/addon/sign.js.map +1 -0
- package/dist/commands/addon/toggle.d.ts +6 -0
- package/dist/commands/addon/toggle.d.ts.map +1 -0
- package/dist/commands/addon/toggle.js +46 -0
- package/dist/commands/addon/toggle.js.map +1 -0
- package/dist/commands/agent/index.d.ts +34 -0
- package/dist/commands/agent/index.d.ts.map +1 -0
- package/dist/commands/agent/index.js +564 -0
- package/dist/commands/agent/index.js.map +1 -0
- package/dist/commands/brand/index.d.ts +54 -0
- package/dist/commands/brand/index.d.ts.map +1 -0
- package/dist/commands/brand/index.js +367 -0
- package/dist/commands/brand/index.js.map +1 -0
- package/dist/commands/build/index.d.ts +53 -0
- package/dist/commands/build/index.d.ts.map +1 -0
- package/dist/commands/build/index.js +726 -0
- package/dist/commands/build/index.js.map +1 -0
- package/dist/commands/cache/flush-local.d.ts +31 -0
- package/dist/commands/cache/flush-local.d.ts.map +1 -0
- package/dist/commands/cache/flush-local.js +161 -0
- package/dist/commands/cache/flush-local.js.map +1 -0
- package/dist/commands/cache/index.d.ts +14 -0
- package/dist/commands/cache/index.d.ts.map +1 -0
- package/dist/commands/cache/index.js +453 -0
- package/dist/commands/cache/index.js.map +1 -0
- package/dist/commands/check/index.d.ts +8 -0
- package/dist/commands/check/index.d.ts.map +1 -0
- package/dist/commands/check/index.js +1316 -0
- package/dist/commands/check/index.js.map +1 -0
- package/dist/commands/cloudflare/index.d.ts +8 -0
- package/dist/commands/cloudflare/index.d.ts.map +1 -0
- package/dist/commands/cloudflare/index.js +453 -0
- package/dist/commands/cloudflare/index.js.map +1 -0
- package/dist/commands/core/create.d.ts +12 -0
- package/dist/commands/core/create.d.ts.map +1 -0
- package/dist/commands/core/create.js +206 -0
- package/dist/commands/core/create.js.map +1 -0
- package/dist/commands/core/delete.d.ts +11 -0
- package/dist/commands/core/delete.d.ts.map +1 -0
- package/dist/commands/core/delete.js +64 -0
- package/dist/commands/core/delete.js.map +1 -0
- package/dist/commands/core/env.d.ts +12 -0
- package/dist/commands/core/env.d.ts.map +1 -0
- package/dist/commands/core/env.js +95 -0
- package/dist/commands/core/env.js.map +1 -0
- package/dist/commands/core/health.d.ts +6 -0
- package/dist/commands/core/health.d.ts.map +1 -0
- package/dist/commands/core/health.js +215 -0
- package/dist/commands/core/health.js.map +1 -0
- package/dist/commands/core/index.d.ts +15 -0
- package/dist/commands/core/index.d.ts.map +1 -0
- package/dist/commands/core/index.js +86 -0
- package/dist/commands/core/index.js.map +1 -0
- package/dist/commands/core/list.d.ts +11 -0
- package/dist/commands/core/list.d.ts.map +1 -0
- package/dist/commands/core/list.js +58 -0
- package/dist/commands/core/list.js.map +1 -0
- package/dist/commands/core/rebuild.d.ts +13 -0
- package/dist/commands/core/rebuild.d.ts.map +1 -0
- package/dist/commands/core/rebuild.js +119 -0
- package/dist/commands/core/rebuild.js.map +1 -0
- package/dist/commands/db/index.d.ts +23 -0
- package/dist/commands/db/index.d.ts.map +1 -0
- package/dist/commands/db/index.js +355 -0
- package/dist/commands/db/index.js.map +1 -0
- package/dist/commands/db/promote-silo.d.ts +320 -0
- package/dist/commands/db/promote-silo.d.ts.map +1 -0
- package/dist/commands/db/promote-silo.js +930 -0
- package/dist/commands/db/promote-silo.js.map +1 -0
- package/dist/commands/db/relocate.d.ts +41 -0
- package/dist/commands/db/relocate.d.ts.map +1 -0
- package/dist/commands/db/relocate.js +482 -0
- package/dist/commands/db/relocate.js.map +1 -0
- package/dist/commands/db/rollback-silo.d.ts +44 -0
- package/dist/commands/db/rollback-silo.d.ts.map +1 -0
- package/dist/commands/db/rollback-silo.js +402 -0
- package/dist/commands/db/rollback-silo.js.map +1 -0
- package/dist/commands/deploy/index.d.ts +26 -0
- package/dist/commands/deploy/index.d.ts.map +1 -0
- package/dist/commands/deploy/index.js +107 -0
- package/dist/commands/deploy/index.js.map +1 -0
- package/dist/commands/devops/index.d.ts +6 -0
- package/dist/commands/devops/index.d.ts.map +1 -0
- package/dist/commands/devops/index.js +220 -0
- package/dist/commands/devops/index.js.map +1 -0
- package/dist/commands/domain/index.d.ts +8 -0
- package/dist/commands/domain/index.d.ts.map +1 -0
- package/dist/commands/domain/index.js +386 -0
- package/dist/commands/domain/index.js.map +1 -0
- package/dist/commands/image/index.d.ts +8 -0
- package/dist/commands/image/index.d.ts.map +1 -0
- package/dist/commands/image/index.js +308 -0
- package/dist/commands/image/index.js.map +1 -0
- package/dist/commands/install/factory-reset.d.ts +21 -0
- package/dist/commands/install/factory-reset.d.ts.map +1 -0
- package/dist/commands/install/factory-reset.js +83 -0
- package/dist/commands/install/factory-reset.js.map +1 -0
- package/dist/commands/install/index.d.ts +17 -0
- package/dist/commands/install/index.d.ts.map +1 -0
- package/dist/commands/install/index.js +44 -0
- package/dist/commands/install/index.js.map +1 -0
- package/dist/commands/install/install.d.ts +35 -0
- package/dist/commands/install/install.d.ts.map +1 -0
- package/dist/commands/install/install.js +171 -0
- package/dist/commands/install/install.js.map +1 -0
- package/dist/commands/login/index.d.ts +15 -0
- package/dist/commands/login/index.d.ts.map +1 -0
- package/dist/commands/login/index.js +58 -0
- package/dist/commands/login/index.js.map +1 -0
- package/dist/commands/nginx/index.d.ts +11 -0
- package/dist/commands/nginx/index.d.ts.map +1 -0
- package/dist/commands/nginx/index.js +580 -0
- package/dist/commands/nginx/index.js.map +1 -0
- package/dist/commands/server/bootstrap.d.ts +25 -0
- package/dist/commands/server/bootstrap.d.ts.map +1 -0
- package/dist/commands/server/bootstrap.js +260 -0
- package/dist/commands/server/bootstrap.js.map +1 -0
- package/dist/commands/server/index.d.ts +8 -0
- package/dist/commands/server/index.d.ts.map +1 -0
- package/dist/commands/server/index.js +2524 -0
- package/dist/commands/server/index.js.map +1 -0
- package/dist/commands/setup/index.d.ts +34 -0
- package/dist/commands/setup/index.d.ts.map +1 -0
- package/dist/commands/setup/index.js +423 -0
- package/dist/commands/setup/index.js.map +1 -0
- package/dist/commands/ssl/index.d.ts +8 -0
- package/dist/commands/ssl/index.d.ts.map +1 -0
- package/dist/commands/ssl/index.js +275 -0
- package/dist/commands/ssl/index.js.map +1 -0
- package/dist/commands/superadmin/index.d.ts +16 -0
- package/dist/commands/superadmin/index.d.ts.map +1 -0
- package/dist/commands/superadmin/index.js +81 -0
- package/dist/commands/superadmin/index.js.map +1 -0
- package/dist/commands/tenant/index.d.ts +6 -0
- package/dist/commands/tenant/index.d.ts.map +1 -0
- package/dist/commands/tenant/index.js +192 -0
- package/dist/commands/tenant/index.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +107 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/addon-sign.d.ts +23 -0
- package/dist/lib/addon-sign.d.ts.map +1 -0
- package/dist/lib/addon-sign.js +39 -0
- package/dist/lib/addon-sign.js.map +1 -0
- package/dist/lib/addon-sign.test.d.ts +2 -0
- package/dist/lib/addon-sign.test.d.ts.map +1 -0
- package/dist/lib/addon-sign.test.js +27 -0
- package/dist/lib/addon-sign.test.js.map +1 -0
- package/dist/lib/cdn.d.ts +25 -0
- package/dist/lib/cdn.d.ts.map +1 -0
- package/dist/lib/cdn.js +131 -0
- package/dist/lib/cdn.js.map +1 -0
- package/dist/lib/cloudflare.d.ts +133 -0
- package/dist/lib/cloudflare.d.ts.map +1 -0
- package/dist/lib/cloudflare.js +435 -0
- package/dist/lib/cloudflare.js.map +1 -0
- package/dist/lib/config.d.ts +96 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +132 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/env.d.ts +8 -0
- package/dist/lib/env.d.ts.map +1 -0
- package/dist/lib/env.js +64 -0
- package/dist/lib/env.js.map +1 -0
- package/dist/lib/hosts.d.ts +194 -0
- package/dist/lib/hosts.d.ts.map +1 -0
- package/dist/lib/hosts.js +183 -0
- package/dist/lib/hosts.js.map +1 -0
- package/dist/lib/logger.d.ts +68 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +130 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/nginx-config.d.ts +78 -0
- package/dist/lib/nginx-config.d.ts.map +1 -0
- package/dist/lib/nginx-config.js +736 -0
- package/dist/lib/nginx-config.js.map +1 -0
- package/dist/lib/ops/addon-dev.d.ts +93 -0
- package/dist/lib/ops/addon-dev.d.ts.map +1 -0
- package/dist/lib/ops/addon-dev.js +237 -0
- package/dist/lib/ops/addon-dev.js.map +1 -0
- package/dist/lib/ops/addon-quality.d.ts +38 -0
- package/dist/lib/ops/addon-quality.d.ts.map +1 -0
- package/dist/lib/ops/addon-quality.js +338 -0
- package/dist/lib/ops/addon-quality.js.map +1 -0
- package/dist/lib/ops/addon-routes.d.ts +49 -0
- package/dist/lib/ops/addon-routes.d.ts.map +1 -0
- package/dist/lib/ops/addon-routes.js +189 -0
- package/dist/lib/ops/addon-routes.js.map +1 -0
- package/dist/lib/ops/addon.d.ts +120 -0
- package/dist/lib/ops/addon.d.ts.map +1 -0
- package/dist/lib/ops/addon.js +260 -0
- package/dist/lib/ops/addon.js.map +1 -0
- package/dist/lib/ops/cdn.d.ts +87 -0
- package/dist/lib/ops/cdn.d.ts.map +1 -0
- package/dist/lib/ops/cdn.js +170 -0
- package/dist/lib/ops/cdn.js.map +1 -0
- package/dist/lib/ops/cf.d.ts +36 -0
- package/dist/lib/ops/cf.d.ts.map +1 -0
- package/dist/lib/ops/cf.js +114 -0
- package/dist/lib/ops/cf.js.map +1 -0
- package/dist/lib/ops/compose.d.ts +95 -0
- package/dist/lib/ops/compose.d.ts.map +1 -0
- package/dist/lib/ops/compose.js +165 -0
- package/dist/lib/ops/compose.js.map +1 -0
- package/dist/lib/ops/core.d.ts +117 -0
- package/dist/lib/ops/core.d.ts.map +1 -0
- package/dist/lib/ops/core.js +322 -0
- package/dist/lib/ops/core.js.map +1 -0
- package/dist/lib/ops/db.d.ts +116 -0
- package/dist/lib/ops/db.d.ts.map +1 -0
- package/dist/lib/ops/db.js +351 -0
- package/dist/lib/ops/db.js.map +1 -0
- package/dist/lib/ops/dns.d.ts +111 -0
- package/dist/lib/ops/dns.d.ts.map +1 -0
- package/dist/lib/ops/dns.js +306 -0
- package/dist/lib/ops/dns.js.map +1 -0
- package/dist/lib/ops/image.d.ts +94 -0
- package/dist/lib/ops/image.d.ts.map +1 -0
- package/dist/lib/ops/image.js +159 -0
- package/dist/lib/ops/image.js.map +1 -0
- package/dist/lib/ops/nginx.d.ts +114 -0
- package/dist/lib/ops/nginx.d.ts.map +1 -0
- package/dist/lib/ops/nginx.js +388 -0
- package/dist/lib/ops/nginx.js.map +1 -0
- package/dist/lib/ops/redis.d.ts +7 -0
- package/dist/lib/ops/redis.d.ts.map +1 -0
- package/dist/lib/ops/redis.js +35 -0
- package/dist/lib/ops/redis.js.map +1 -0
- package/dist/lib/ops/ssh.d.ts +127 -0
- package/dist/lib/ops/ssh.d.ts.map +1 -0
- package/dist/lib/ops/ssh.js +269 -0
- package/dist/lib/ops/ssh.js.map +1 -0
- package/dist/lib/prompts.d.ts +46 -0
- package/dist/lib/prompts.d.ts.map +1 -0
- package/dist/lib/prompts.js +113 -0
- package/dist/lib/prompts.js.map +1 -0
- package/dist/lib/sast.d.ts +43 -0
- package/dist/lib/sast.d.ts.map +1 -0
- package/dist/lib/sast.js +79 -0
- package/dist/lib/sast.js.map +1 -0
- package/dist/lib/sast.test.d.ts +2 -0
- package/dist/lib/sast.test.d.ts.map +1 -0
- package/dist/lib/sast.test.js +33 -0
- package/dist/lib/sast.test.js.map +1 -0
- package/dist/lib/shell.d.ts +61 -0
- package/dist/lib/shell.d.ts.map +1 -0
- package/dist/lib/shell.js +183 -0
- package/dist/lib/shell.js.map +1 -0
- package/dist/lib/ssh-config.d.ts +37 -0
- package/dist/lib/ssh-config.d.ts.map +1 -0
- package/dist/lib/ssh-config.js +122 -0
- package/dist/lib/ssh-config.js.map +1 -0
- package/dist/lib/tenant-scope.d.ts +38 -0
- package/dist/lib/tenant-scope.d.ts.map +1 -0
- package/dist/lib/tenant-scope.js +129 -0
- package/dist/lib/tenant-scope.js.map +1 -0
- package/dist/lib/tenant-scope.test.d.ts +2 -0
- package/dist/lib/tenant-scope.test.d.ts.map +1 -0
- package/dist/lib/tenant-scope.test.js +223 -0
- package/dist/lib/tenant-scope.test.js.map +1 -0
- package/package.json +58 -0
- package/templates/bootstrap/.env.template +54 -0
- package/templates/bootstrap/docker-compose.yml +145 -0
- package/templates/vhost.conf.tmpl +446 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tenant-scope static analysis — T-C trust-boundary deploy gate (task-230).
|
|
3
|
+
*
|
|
4
|
+
* Addon Backend PHP'si paylaşımlı cicore_php-FPM içinde çalışır. Yanlış yazılmış
|
|
5
|
+
* bir addon DatabaseService'i doğrudan çağırarak TenantContext'i bypass edip başka
|
|
6
|
+
* tenant'ın verisine erişebilir.
|
|
7
|
+
*
|
|
8
|
+
* Tarama iki katmanda çalışır:
|
|
9
|
+
* 1. Orijinal satır bazlı — kesin satır numarası üretir.
|
|
10
|
+
* 2. Whitespace-normalize (tek satır) — multi-line split kaçağını kapatır.
|
|
11
|
+
*
|
|
12
|
+
* Ayrıca PHP class alias (`use ... as Alias`) tespiti yapılır; her alias için
|
|
13
|
+
* forbidden pattern'lar dinamik olarak üretilir.
|
|
14
|
+
*
|
|
15
|
+
* Sınır: statik regex (AST değil). Obfuscated runtime bypass → FAZ-2 sandbox (Hünkar).
|
|
16
|
+
*/
|
|
17
|
+
const TENANT_SAFE_PATTERNS = [
|
|
18
|
+
/TenantContext::current\(\)/,
|
|
19
|
+
/TenantDbResolver/,
|
|
20
|
+
];
|
|
21
|
+
/** Regex özel karakterlerini escape et. */
|
|
22
|
+
function esc(s) {
|
|
23
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* PHP 'use ... as Alias' ifadelerinden DatabaseService alias listesi çıkarır.
|
|
27
|
+
* 'DatabaseService' her zaman dahil (alias olmayan doğrudan kullanım).
|
|
28
|
+
*/
|
|
29
|
+
function extractDbAliases(content) {
|
|
30
|
+
const aliases = ['DatabaseService'];
|
|
31
|
+
const re = /use\s+(?:[\w\\]+\\)?DatabaseService\s+as\s+(\w+)\s*;/g;
|
|
32
|
+
let m;
|
|
33
|
+
while ((m = re.exec(content)) !== null) {
|
|
34
|
+
if (!aliases.includes(m[1]))
|
|
35
|
+
aliases.push(m[1]);
|
|
36
|
+
}
|
|
37
|
+
return aliases;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Tüm whitespace dizilerini tek boşluğa indirir — satır kırıkları da dahil.
|
|
41
|
+
* Multi-line pattern split kaçağını tek-satıra getirerek kapatır.
|
|
42
|
+
*/
|
|
43
|
+
function flattenWhitespace(content) {
|
|
44
|
+
return content.replace(/\s+/g, ' ');
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Orijinal satırları tarayarak kesin satır numarası üretir (1-tabanlı).
|
|
48
|
+
* Eşleşen satır yoksa -1 döner (normalize-path için çağıran line:0 atar).
|
|
49
|
+
*/
|
|
50
|
+
function findLine(lines, pattern) {
|
|
51
|
+
const idx = lines.findIndex((l) => pattern.test(l));
|
|
52
|
+
return idx >= 0 ? idx + 1 : -1;
|
|
53
|
+
}
|
|
54
|
+
function addViolation(violations, file, line, rule, detail) {
|
|
55
|
+
violations.push({ file, line, rule, detail });
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Analyzes a list of Backend PHP files for tenant-scope violations.
|
|
59
|
+
* Pure function (no filesystem I/O) — testable without disk.
|
|
60
|
+
*/
|
|
61
|
+
export function analyzeTenantScope(files) {
|
|
62
|
+
if (files.length === 0) {
|
|
63
|
+
return { violations: [], tenantContextUsed: false, hasBackendFiles: false, ok: true };
|
|
64
|
+
}
|
|
65
|
+
const violations = [];
|
|
66
|
+
let tenantContextUsed = false;
|
|
67
|
+
for (const { path: filePath, content } of files) {
|
|
68
|
+
if (TENANT_SAFE_PATTERNS.some((p) => p.test(content))) {
|
|
69
|
+
tenantContextUsed = true;
|
|
70
|
+
}
|
|
71
|
+
const aliases = extractDbAliases(content);
|
|
72
|
+
const flat = flattenWhitespace(content);
|
|
73
|
+
const lines = content.split('\n');
|
|
74
|
+
// ── FORBIDDEN-1: Alias::getConnection() direkt çağrı ─────────────────
|
|
75
|
+
for (const alias of aliases) {
|
|
76
|
+
const pat = new RegExp(`${esc(alias)}::getConnection\\s*\\(\\s*\\)`);
|
|
77
|
+
// Katman-1: satır bazlı (kesin satır numarası)
|
|
78
|
+
lines.forEach((line, idx) => {
|
|
79
|
+
if (pat.test(line)) {
|
|
80
|
+
addViolation(violations, filePath, idx + 1, 'direct-db-connection', `Direct ${alias}::getConnection() bypasses TenantContext — use TenantDbResolver. ` +
|
|
81
|
+
`(found: "${line.trim().slice(0, 80)}")`);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
// Katman-2: normalize (multi-line split'i kapatır; line:0 = dosya-seviyesi)
|
|
85
|
+
if (pat.test(flat) && !lines.some((l) => pat.test(l))) {
|
|
86
|
+
addViolation(violations, filePath, 0, 'direct-db-connection', `Direct ${alias}::getConnection() bypasses TenantContext (multi-line split detected) — use TenantDbResolver.`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// ── FORBIDDEN-2: Alias::getGatewayInstance()->getConnection() ─────────
|
|
90
|
+
for (const alias of aliases) {
|
|
91
|
+
// 2a. Inline (tek satır veya whitespace-normalize birleşimi)
|
|
92
|
+
const inlinePat = new RegExp(`${esc(alias)}::getGatewayInstance\\s*\\(\\s*\\)\\s*->\\s*getConnection\\s*\\(\\s*\\)`);
|
|
93
|
+
lines.forEach((line, idx) => {
|
|
94
|
+
if (inlinePat.test(line)) {
|
|
95
|
+
addViolation(violations, filePath, idx + 1, 'unguarded-gateway', `Unguarded ${alias}::getGatewayInstance()->getConnection() — use TenantDbResolver. ` +
|
|
96
|
+
`(found: "${line.trim().slice(0, 80)}")`);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
if (inlinePat.test(flat) && !lines.some((l) => inlinePat.test(l))) {
|
|
100
|
+
addViolation(violations, filePath, 0, 'unguarded-gateway', `Unguarded ${alias}::getGatewayInstance()->getConnection() (multi-line) — use TenantDbResolver.`);
|
|
101
|
+
}
|
|
102
|
+
// 2b. 2-step: $var = Alias::getGatewayInstance(); ... $var->getConnection()
|
|
103
|
+
// Normalize üzerinde: değişken atama → aynı değişken üzerinden ->getConnection()
|
|
104
|
+
const assignPat = new RegExp(`(\\$\\w+)\\s*=\\s*${esc(alias)}::getGatewayInstance\\s*\\(\\s*\\)`);
|
|
105
|
+
const assignMatch = assignPat.exec(flat);
|
|
106
|
+
if (assignMatch) {
|
|
107
|
+
const varName = assignMatch[1];
|
|
108
|
+
const usePat = new RegExp(`${esc(varName)}\\s*->\\s*getConnection\\s*\\(\\s*\\)`);
|
|
109
|
+
if (usePat.test(flat)) {
|
|
110
|
+
const assignLine = findLine(lines, new RegExp(`\\$\\w+\\s*=\\s*${esc(alias)}::getGatewayInstance\\s*\\(\\s*\\)`));
|
|
111
|
+
addViolation(violations, filePath, assignLine > 0 ? assignLine : 0, 'unguarded-gateway', `${varName} = ${alias}::getGatewayInstance() stored and ->getConnection() called later ` +
|
|
112
|
+
`(two-step pattern) — use TenantDbResolver.`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Backend dosyası var ama hiç TenantContext/TenantDbResolver yok
|
|
118
|
+
if (!tenantContextUsed) {
|
|
119
|
+
addViolation(violations, '<addon/Backend>', 0, 'no-tenant-context', 'No TenantContext::current() or TenantDbResolver found in any backend file — ' +
|
|
120
|
+
'tenant isolation cannot be verified. Add TenantContext::current() to all DB-accessing services.');
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
violations,
|
|
124
|
+
tenantContextUsed,
|
|
125
|
+
hasBackendFiles: true,
|
|
126
|
+
ok: violations.length === 0,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=tenant-scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-scope.js","sourceRoot":"","sources":["../../src/lib/tenant-scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAqBH,MAAM,oBAAoB,GAAG;IAC3B,4BAA4B;IAC5B,kBAAkB;CACnB,CAAA;AAED,2CAA2C;AAC3C,SAAS,GAAG,CAAC,CAAS;IACpB,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA;AACjD,CAAC;AAED;;;GAGG;AACH,SAAS,gBAAgB,CAAC,OAAe;IACvC,MAAM,OAAO,GAAG,CAAC,iBAAiB,CAAC,CAAA;IACnC,MAAM,EAAE,GAAG,uDAAuD,CAAA;IAClE,IAAI,CAAyB,CAAA;IAC7B,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACvC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACjD,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,OAAe;IACxC,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AACrC,CAAC;AAED;;;GAGG;AACH,SAAS,QAAQ,CAAC,KAAe,EAAE,OAAe;IAChD,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IACnD,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAChC,CAAC;AAED,SAAS,YAAY,CACnB,UAAkC,EAClC,IAAY,EACZ,IAAY,EACZ,IAAY,EACZ,MAAc;IAEd,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;AAC/C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAkB;IACnD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,iBAAiB,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,CAAA;IACvF,CAAC;IAED,MAAM,UAAU,GAA2B,EAAE,CAAA;IAC7C,IAAI,iBAAiB,GAAG,KAAK,CAAA;IAE7B,KAAK,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,KAAK,EAAE,CAAC;QAChD,IAAI,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;YACtD,iBAAiB,GAAG,IAAI,CAAA;QAC1B,CAAC;QAED,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;QACzC,MAAM,IAAI,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAA;QACvC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAEjC,wEAAwE;QACxE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAA;YAEpE,+CAA+C;YAC/C,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;gBAC1B,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACnB,YAAY,CACV,UAAU,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC,EAAE,sBAAsB,EACrD,UAAU,KAAK,mEAAmE;wBAClF,YAAY,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CACzC,CAAA;gBACH,CAAC;YACH,CAAC,CAAC,CAAA;YAEF,4EAA4E;YAC5E,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACtD,YAAY,CACV,UAAU,EAAE,QAAQ,EAAE,CAAC,EAAE,sBAAsB,EAC/C,UAAU,KAAK,8FAA8F,CAC9G,CAAA;YACH,CAAC;QACH,CAAC;QAED,yEAAyE;QACzE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,6DAA6D;YAC7D,MAAM,SAAS,GAAG,IAAI,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,yEAAyE,CAAC,CAAA;YAEpH,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;gBAC1B,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACzB,YAAY,CACV,UAAU,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC,EAAE,mBAAmB,EAClD,aAAa,KAAK,kEAAkE;wBACpF,YAAY,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CACzC,CAAA;gBACH,CAAC;YACH,CAAC,CAAC,CAAA;YAEF,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClE,YAAY,CACV,UAAU,EAAE,QAAQ,EAAE,CAAC,EAAE,mBAAmB,EAC5C,aAAa,KAAK,8EAA8E,CACjG,CAAA;YACH,CAAC;YAED,4EAA4E;YAC5E,qFAAqF;YACrF,MAAM,SAAS,GAAG,IAAI,MAAM,CAAC,qBAAqB,GAAG,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAA;YACjG,MAAM,WAAW,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACxC,IAAI,WAAW,EAAE,CAAC;gBAChB,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;gBAC9B,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAA;gBACjF,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACtB,MAAM,UAAU,GAAG,QAAQ,CACzB,KAAK,EACL,IAAI,MAAM,CAAC,mBAAmB,GAAG,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAC9E,CAAA;oBACD,YAAY,CACV,UAAU,EAAE,QAAQ,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,mBAAmB,EAC1E,GAAG,OAAO,MAAM,KAAK,mEAAmE;wBACxF,4CAA4C,CAC7C,CAAA;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,iEAAiE;IACjE,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,YAAY,CACV,UAAU,EAAE,iBAAiB,EAAE,CAAC,EAAE,mBAAmB,EACrD,8EAA8E;YAC9E,iGAAiG,CAClG,CAAA;IACH,CAAC;IAED,OAAO;QACL,UAAU;QACV,iBAAiB;QACjB,eAAe,EAAE,IAAI;QACrB,EAAE,EAAE,UAAU,CAAC,MAAM,KAAK,CAAC;KAC5B,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-scope.test.d.ts","sourceRoot":"","sources":["../../src/lib/tenant-scope.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { analyzeTenantScope } from './tenant-scope.js';
|
|
3
|
+
describe('tenant-scope / T-C trust-boundary deploy gate (task-230)', () => {
|
|
4
|
+
// ── temiz addon ─────────────────────────────────────────────────────
|
|
5
|
+
it('dosya yoksa ok=true, hasBackendFiles=false (backend-siz addon geçer)', () => {
|
|
6
|
+
const result = analyzeTenantScope([]);
|
|
7
|
+
expect(result.ok).toBe(true);
|
|
8
|
+
expect(result.hasBackendFiles).toBe(false);
|
|
9
|
+
expect(result.violations).toHaveLength(0);
|
|
10
|
+
});
|
|
11
|
+
it('TenantContext::current() kullanan addon → temiz (deploy GEÇER)', () => {
|
|
12
|
+
const result = analyzeTenantScope([
|
|
13
|
+
{
|
|
14
|
+
path: 'Backend/Services/MyService.php',
|
|
15
|
+
content: [
|
|
16
|
+
'<?php',
|
|
17
|
+
'use VuCore\\Core\\Services\\TenantContext;',
|
|
18
|
+
'$tenant = TenantContext::current();',
|
|
19
|
+
'$db = $tenant->db();',
|
|
20
|
+
'$stmt = $db->query("SELECT * FROM widgets WHERE tenant_id = :tid");',
|
|
21
|
+
].join('\n'),
|
|
22
|
+
},
|
|
23
|
+
]);
|
|
24
|
+
expect(result.ok).toBe(true);
|
|
25
|
+
expect(result.tenantContextUsed).toBe(true);
|
|
26
|
+
expect(result.violations).toHaveLength(0);
|
|
27
|
+
});
|
|
28
|
+
it('TenantDbResolver kullanan addon → temiz (deploy GEÇER)', () => {
|
|
29
|
+
const result = analyzeTenantScope([
|
|
30
|
+
{
|
|
31
|
+
path: 'Backend/Services/OrderService.php',
|
|
32
|
+
content: '<?php\n$db = TenantDbResolver::resolve($slug);\n',
|
|
33
|
+
},
|
|
34
|
+
]);
|
|
35
|
+
expect(result.ok).toBe(true);
|
|
36
|
+
expect(result.violations).toHaveLength(0);
|
|
37
|
+
});
|
|
38
|
+
// ── adversarial: kötü addon, deploy RED ──────────────────────────────
|
|
39
|
+
it('[ADVERSARIAL] DatabaseService::getConnection() direkt çağrı → violation + deploy RED', () => {
|
|
40
|
+
const result = analyzeTenantScope([
|
|
41
|
+
{
|
|
42
|
+
path: 'Backend/Services/BadService.php',
|
|
43
|
+
content: [
|
|
44
|
+
'<?php',
|
|
45
|
+
'// Kötü addon: TenantContext yok, direkt DB bağlantısı',
|
|
46
|
+
'$pdo = \\VuCore\\Core\\Services\\DatabaseService::getConnection();',
|
|
47
|
+
'$stmt = $pdo->query("SELECT * FROM all_tenants_data");',
|
|
48
|
+
].join('\n'),
|
|
49
|
+
},
|
|
50
|
+
]);
|
|
51
|
+
expect(result.ok).toBe(false);
|
|
52
|
+
expect(result.tenantContextUsed).toBe(false);
|
|
53
|
+
const rules = result.violations.map((v) => v.rule);
|
|
54
|
+
expect(rules).toContain('direct-db-connection');
|
|
55
|
+
expect(rules).toContain('no-tenant-context');
|
|
56
|
+
});
|
|
57
|
+
it('[ADVERSARIAL] getGatewayInstance()->getConnection() unguarded → violation + deploy RED', () => {
|
|
58
|
+
const result = analyzeTenantScope([
|
|
59
|
+
{
|
|
60
|
+
path: 'Backend/Controllers/BadController.php',
|
|
61
|
+
content: [
|
|
62
|
+
'<?php',
|
|
63
|
+
'$db = DatabaseService::getGatewayInstance()->getConnection();',
|
|
64
|
+
].join('\n'),
|
|
65
|
+
},
|
|
66
|
+
]);
|
|
67
|
+
expect(result.ok).toBe(false);
|
|
68
|
+
const rules = result.violations.map((v) => v.rule);
|
|
69
|
+
expect(rules).toContain('unguarded-gateway');
|
|
70
|
+
expect(rules).toContain('no-tenant-context');
|
|
71
|
+
});
|
|
72
|
+
it('[ADVERSARIAL] TenantContext var AMA direkt getConnection() de var → violation (deploy RED)', () => {
|
|
73
|
+
// TenantContext kullanıyor ama yine de direkt bypass da yapıyor
|
|
74
|
+
const result = analyzeTenantScope([
|
|
75
|
+
{
|
|
76
|
+
path: 'Backend/Services/HybridService.php',
|
|
77
|
+
content: [
|
|
78
|
+
'<?php',
|
|
79
|
+
'$tenant = TenantContext::current(); // iyi',
|
|
80
|
+
'$adminDb = DatabaseService::getConnection(); // BU YASAK',
|
|
81
|
+
].join('\n'),
|
|
82
|
+
},
|
|
83
|
+
]);
|
|
84
|
+
expect(result.ok).toBe(false);
|
|
85
|
+
expect(result.tenantContextUsed).toBe(true); // tenantContext var ama...
|
|
86
|
+
const rules = result.violations.map((v) => v.rule);
|
|
87
|
+
expect(rules).toContain('direct-db-connection');
|
|
88
|
+
expect(rules).not.toContain('no-tenant-context'); // TC var, o violation yok
|
|
89
|
+
});
|
|
90
|
+
// ── çoklu dosya ────────────────────────────────────────────────────
|
|
91
|
+
it('çoklu dosya: biri temiz biri kötü → violation + deploy RED', () => {
|
|
92
|
+
const result = analyzeTenantScope([
|
|
93
|
+
{
|
|
94
|
+
path: 'Backend/Services/GoodService.php',
|
|
95
|
+
content: '$tenant = TenantContext::current();',
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
path: 'Backend/Services/BadService.php',
|
|
99
|
+
content: '$db = DatabaseService::getConnection(); // bypass',
|
|
100
|
+
},
|
|
101
|
+
]);
|
|
102
|
+
expect(result.ok).toBe(false);
|
|
103
|
+
expect(result.tenantContextUsed).toBe(true);
|
|
104
|
+
expect(result.violations.some((v) => v.file === 'Backend/Services/BadService.php')).toBe(true);
|
|
105
|
+
});
|
|
106
|
+
// ── violation detay yapısı ─────────────────────────────────────────
|
|
107
|
+
it('violation satır numarası doğru (1-tabanlı)', () => {
|
|
108
|
+
const result = analyzeTenantScope([
|
|
109
|
+
{
|
|
110
|
+
path: 'Backend/Services/LineTest.php',
|
|
111
|
+
content: '<?php\n\n$db = DatabaseService::getConnection();\n',
|
|
112
|
+
},
|
|
113
|
+
]);
|
|
114
|
+
const v = result.violations.find((x) => x.rule === 'direct-db-connection');
|
|
115
|
+
expect(v).toBeDefined();
|
|
116
|
+
expect(v.line).toBe(3);
|
|
117
|
+
});
|
|
118
|
+
// ── kaçak-1: PHP class alias (CHANGES_REQUESTED) ───────────────────
|
|
119
|
+
it('[ADVERSARIAL][kaçak-1] use DatabaseService as DB; DB::getConnection() → violation (deploy RED)', () => {
|
|
120
|
+
// Alias kullanımı: forbidden regex orijinal ismi aramaz, alias yakalanmalı
|
|
121
|
+
const result = analyzeTenantScope([
|
|
122
|
+
{
|
|
123
|
+
path: 'Backend/Services/AliasedService.php',
|
|
124
|
+
content: [
|
|
125
|
+
'<?php',
|
|
126
|
+
'use VuCore\\Core\\Services\\DatabaseService as DB;',
|
|
127
|
+
'// TenantContext yok, alias ile direkt bağlantı',
|
|
128
|
+
'$pdo = DB::getConnection();',
|
|
129
|
+
'$stmt = $pdo->query("SELECT * FROM all_data");',
|
|
130
|
+
].join('\n'),
|
|
131
|
+
},
|
|
132
|
+
]);
|
|
133
|
+
expect(result.ok).toBe(false);
|
|
134
|
+
const rules = result.violations.map((v) => v.rule);
|
|
135
|
+
expect(rules).toContain('direct-db-connection');
|
|
136
|
+
expect(rules).toContain('no-tenant-context');
|
|
137
|
+
const v = result.violations.find((x) => x.rule === 'direct-db-connection');
|
|
138
|
+
expect(v?.detail).toMatch(/DB::getConnection/);
|
|
139
|
+
expect(v?.line).toBe(4);
|
|
140
|
+
});
|
|
141
|
+
it('[ADVERSARIAL][kaçak-1] alias ile getGatewayInstance()->getConnection() → violation (deploy RED)', () => {
|
|
142
|
+
const result = analyzeTenantScope([
|
|
143
|
+
{
|
|
144
|
+
path: 'Backend/Services/AliasGateway.php',
|
|
145
|
+
content: [
|
|
146
|
+
'<?php',
|
|
147
|
+
'use VuCore\\Core\\Services\\DatabaseService as Svc;',
|
|
148
|
+
'$db = Svc::getGatewayInstance()->getConnection();',
|
|
149
|
+
].join('\n'),
|
|
150
|
+
},
|
|
151
|
+
]);
|
|
152
|
+
expect(result.ok).toBe(false);
|
|
153
|
+
const rules = result.violations.map((v) => v.rule);
|
|
154
|
+
expect(rules).toContain('unguarded-gateway');
|
|
155
|
+
});
|
|
156
|
+
// ── kaçak-2: multi-line getGatewayInstance split (CHANGES_REQUESTED) ──
|
|
157
|
+
it('[ADVERSARIAL][kaçak-2] $gw = getGatewayInstance(); ayrı satır $gw->getConnection() → violation (deploy RED)', () => {
|
|
158
|
+
const result = analyzeTenantScope([
|
|
159
|
+
{
|
|
160
|
+
path: 'Backend/Services/MultiLineGateway.php',
|
|
161
|
+
content: [
|
|
162
|
+
'<?php',
|
|
163
|
+
'// Kötü addon: 2-step split, tek satır regex yakalamazdı',
|
|
164
|
+
'$gw = DatabaseService::getGatewayInstance();',
|
|
165
|
+
'someOtherCall();',
|
|
166
|
+
'$db = $gw->getConnection();',
|
|
167
|
+
].join('\n'),
|
|
168
|
+
},
|
|
169
|
+
]);
|
|
170
|
+
expect(result.ok).toBe(false);
|
|
171
|
+
const rules = result.violations.map((v) => v.rule);
|
|
172
|
+
expect(rules).toContain('unguarded-gateway');
|
|
173
|
+
const v = result.violations.find((x) => x.rule === 'unguarded-gateway');
|
|
174
|
+
expect(v?.detail).toMatch(/\$gw.*getGatewayInstance.*two-step|multi-line/i);
|
|
175
|
+
});
|
|
176
|
+
it('[ADVERSARIAL][kaçak-2] alias + multi-line split → violation (deploy RED)', () => {
|
|
177
|
+
const result = analyzeTenantScope([
|
|
178
|
+
{
|
|
179
|
+
path: 'Backend/Controllers/AliasMultiLine.php',
|
|
180
|
+
content: [
|
|
181
|
+
'<?php',
|
|
182
|
+
'use VuCore\\Core\\Services\\DatabaseService as DS;',
|
|
183
|
+
'$gateway = DS::getGatewayInstance();',
|
|
184
|
+
'$pdo = $gateway->getConnection();',
|
|
185
|
+
].join('\n'),
|
|
186
|
+
},
|
|
187
|
+
]);
|
|
188
|
+
expect(result.ok).toBe(false);
|
|
189
|
+
const rules = result.violations.map((v) => v.rule);
|
|
190
|
+
expect(rules).toContain('unguarded-gateway');
|
|
191
|
+
});
|
|
192
|
+
// ── kaçak-3: parantez boşluk toleransı (CHANGES_REQUESTED 3. tur) ───
|
|
193
|
+
it('[ADVERSARIAL][kaçak-3] getConnection ( ) boşluklu parantez → violation (deploy RED)', () => {
|
|
194
|
+
const result = analyzeTenantScope([
|
|
195
|
+
{
|
|
196
|
+
path: 'Backend/Services/SpacedParen.php',
|
|
197
|
+
content: [
|
|
198
|
+
'<?php',
|
|
199
|
+
'// Kötü addon: getConnection ( ) boşluklu — önceki regex kaçırırdı',
|
|
200
|
+
'$db = DatabaseService::getConnection ( );',
|
|
201
|
+
].join('\n'),
|
|
202
|
+
},
|
|
203
|
+
]);
|
|
204
|
+
expect(result.ok).toBe(false);
|
|
205
|
+
const rules = result.violations.map((v) => v.rule);
|
|
206
|
+
expect(rules).toContain('direct-db-connection');
|
|
207
|
+
});
|
|
208
|
+
it('[ADVERSARIAL][kaçak-3] getGatewayInstance () -> getConnection () boşluklu → violation (deploy RED)', () => {
|
|
209
|
+
const result = analyzeTenantScope([
|
|
210
|
+
{
|
|
211
|
+
path: 'Backend/Services/SpacedGateway.php',
|
|
212
|
+
content: [
|
|
213
|
+
'<?php',
|
|
214
|
+
'$db = DatabaseService::getGatewayInstance () -> getConnection ();',
|
|
215
|
+
].join('\n'),
|
|
216
|
+
},
|
|
217
|
+
]);
|
|
218
|
+
expect(result.ok).toBe(false);
|
|
219
|
+
const rules = result.violations.map((v) => v.rule);
|
|
220
|
+
expect(rules).toContain('unguarded-gateway');
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
//# sourceMappingURL=tenant-scope.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-scope.test.js","sourceRoot":"","sources":["../../src/lib/tenant-scope.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cicore/cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "ciCore Platform CLI - Multi-Core SaaS Management Tool",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"ci": "./bin/ci.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsc --watch",
|
|
13
|
+
"start": "node dist/index.js",
|
|
14
|
+
"link": "npm link",
|
|
15
|
+
"test": "vitest"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"cicore",
|
|
19
|
+
"cli",
|
|
20
|
+
"saas",
|
|
21
|
+
"multi-tenant",
|
|
22
|
+
"addon"
|
|
23
|
+
],
|
|
24
|
+
"author": "ciCore Team",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@types/archiver": "^7.0.0",
|
|
28
|
+
"archiver": "^7.0.1",
|
|
29
|
+
"chalk": "^5.3.0",
|
|
30
|
+
"commander": "^12.1.0",
|
|
31
|
+
"conf": "^13.0.1",
|
|
32
|
+
"enquirer": "^2.4.1",
|
|
33
|
+
"execa": "^9.5.1",
|
|
34
|
+
"fs-extra": "^11.2.0",
|
|
35
|
+
"glob": "^11.0.0",
|
|
36
|
+
"ora": "^8.1.1",
|
|
37
|
+
"table": "^6.8.2",
|
|
38
|
+
"yaml": "^2.6.1"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/fs-extra": "^11.0.4",
|
|
42
|
+
"@types/node": "^22.10.1",
|
|
43
|
+
"typescript": "^5.7.2",
|
|
44
|
+
"vitest": "^2.1.8"
|
|
45
|
+
},
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=20.0.0"
|
|
48
|
+
},
|
|
49
|
+
"files": [
|
|
50
|
+
"dist",
|
|
51
|
+
"bin",
|
|
52
|
+
"templates"
|
|
53
|
+
],
|
|
54
|
+
"publishConfig": {
|
|
55
|
+
"access": "public",
|
|
56
|
+
"registry": "https://registry.npmjs.org/"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# cicore — .env (bootstrap tarafından üretildi)
|
|
2
|
+
# IMAGE-ONLY: kaynak kodu inmez, her şey Docker imajından gelir.
|
|
3
|
+
# Değiştirmek için: nano /opt/cicore/.env → docker compose up -d
|
|
4
|
+
|
|
5
|
+
# ── Versiyon + Registry ───────────────────────────────────────────────────────
|
|
6
|
+
CICORE_IMAGE_TAG=__IMAGE_TAG__
|
|
7
|
+
CICORE_REGISTRY=__REGISTRY__
|
|
8
|
+
|
|
9
|
+
# ── Uygulama ──────────────────────────────────────────────────────────────────
|
|
10
|
+
APP_ENV=production
|
|
11
|
+
APP_DEBUG=false
|
|
12
|
+
APP_KEY=__APP_KEY__
|
|
13
|
+
|
|
14
|
+
# ── Erişim noktaları ─────────────────────────────────────────────────────────
|
|
15
|
+
HTTP_PORT=80
|
|
16
|
+
HTTPS_PORT=443
|
|
17
|
+
TIMEZONE=Europe/Istanbul
|
|
18
|
+
|
|
19
|
+
# ── Veritabanı ───────────────────────────────────────────────────────────────
|
|
20
|
+
DB_NAME=cicore_db
|
|
21
|
+
DB_USER=cicore
|
|
22
|
+
DB_PASS=__DB_PASS__
|
|
23
|
+
DB_GATEWAY=local
|
|
24
|
+
POSTGRES_USER=postgres
|
|
25
|
+
POSTGRES_PASSWORD=__POSTGRES_PASSWORD__
|
|
26
|
+
CONTROL_PLANE_DSN=
|
|
27
|
+
|
|
28
|
+
# ── Redis ────────────────────────────────────────────────────────────────────
|
|
29
|
+
REDIS_PASSWORD=__REDIS_PASSWORD__
|
|
30
|
+
|
|
31
|
+
# ── JWT ──────────────────────────────────────────────────────────────────────
|
|
32
|
+
JWT_SECRET=__JWT_SECRET__
|
|
33
|
+
|
|
34
|
+
# ── Nuxt (domain sonradan ayarlanır) ─────────────────────────────────────────
|
|
35
|
+
NUXT_PUBLIC_HOST=
|
|
36
|
+
NUXT_PUBLIC_API_BASE=
|
|
37
|
+
NUXT_PUBLIC_WS_URL=
|
|
38
|
+
|
|
39
|
+
# ── Ödeme (v1 = mock) ────────────────────────────────────────────────────────
|
|
40
|
+
CICORE_PAYMENT_GATEWAY=mock
|
|
41
|
+
CICORE_PAYMENT_WEBHOOK_SECRET=__WEBHOOK_SECRET__
|
|
42
|
+
|
|
43
|
+
# ── KASA (INST-3 ile aktif olur) ─────────────────────────────────────────────
|
|
44
|
+
KASA_BASE_URL=
|
|
45
|
+
KASA_SERVICE_TOKEN=
|
|
46
|
+
KASA_SSH_AUTHORITY=false
|
|
47
|
+
KASA_LICENSE_AUTHORITY=false
|
|
48
|
+
|
|
49
|
+
# ── Deployment (v1 = mock; INST-5 ile değişir) ───────────────────────────────
|
|
50
|
+
DEPLOYMENT_MOCK=false
|
|
51
|
+
|
|
52
|
+
# ── Registry kimliği (INST-2: per-müşteri pull-token) ────────────────────────
|
|
53
|
+
CICORE_REGISTRY_CREDENTIAL_ID=
|
|
54
|
+
CICORE_CP_BASE_URL=https://cicore.com.tr
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# ══════════════════════════════════════════════════════════════════
|
|
2
|
+
# CiCore — docker-compose.yml (IMAGE-ONLY · bootstrap canonical)
|
|
3
|
+
# Kaynak kodu YOK — her şey cisofttr/* imajından gelir.
|
|
4
|
+
# Üretildi: ci server bootstrap | drift = bloker (installer/ ile sync)
|
|
5
|
+
# ══════════════════════════════════════════════════════════════════
|
|
6
|
+
|
|
7
|
+
services:
|
|
8
|
+
|
|
9
|
+
cicore_postgres:
|
|
10
|
+
image: postgres:16-alpine
|
|
11
|
+
container_name: cicore_postgres
|
|
12
|
+
restart: unless-stopped
|
|
13
|
+
environment:
|
|
14
|
+
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
|
15
|
+
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
16
|
+
POSTGRES_DB: postgres
|
|
17
|
+
TZ: ${TIMEZONE:-Europe/Istanbul}
|
|
18
|
+
volumes:
|
|
19
|
+
- ./data/postgres:/var/lib/postgresql/data
|
|
20
|
+
- ./postgres-init:/docker-entrypoint-initdb.d:ro
|
|
21
|
+
healthcheck:
|
|
22
|
+
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
|
23
|
+
interval: 5s
|
|
24
|
+
timeout: 5s
|
|
25
|
+
retries: 10
|
|
26
|
+
start_period: 10s
|
|
27
|
+
command: >
|
|
28
|
+
postgres
|
|
29
|
+
-c max_connections=200
|
|
30
|
+
-c superuser_reserved_connections=5
|
|
31
|
+
-c shared_buffers=256MB
|
|
32
|
+
-c effective_cache_size=1GB
|
|
33
|
+
-c maintenance_work_mem=64MB
|
|
34
|
+
-c work_mem=4MB
|
|
35
|
+
-c idle_in_transaction_session_timeout=30000
|
|
36
|
+
-c statement_timeout=60000
|
|
37
|
+
networks:
|
|
38
|
+
- cicore_internal
|
|
39
|
+
|
|
40
|
+
cicore_redis:
|
|
41
|
+
image: redis:7-alpine
|
|
42
|
+
container_name: cicore_redis
|
|
43
|
+
restart: unless-stopped
|
|
44
|
+
command: >
|
|
45
|
+
redis-server
|
|
46
|
+
--requirepass ${REDIS_PASSWORD}
|
|
47
|
+
--appendonly yes
|
|
48
|
+
volumes:
|
|
49
|
+
- ./data/redis:/data
|
|
50
|
+
healthcheck:
|
|
51
|
+
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
|
|
52
|
+
interval: 5s
|
|
53
|
+
timeout: 3s
|
|
54
|
+
retries: 5
|
|
55
|
+
networks:
|
|
56
|
+
- cicore_internal
|
|
57
|
+
|
|
58
|
+
cicore_php:
|
|
59
|
+
image: ${CICORE_REGISTRY:-cisofttr}/cicore-php:${CICORE_IMAGE_TAG:-b11}
|
|
60
|
+
container_name: cicore_php
|
|
61
|
+
restart: unless-stopped
|
|
62
|
+
environment:
|
|
63
|
+
APP_ENV: ${APP_ENV:-production}
|
|
64
|
+
APP_DEBUG: ${APP_DEBUG:-false}
|
|
65
|
+
APP_KEY: ${APP_KEY}
|
|
66
|
+
DB_GATEWAY: ${DB_GATEWAY:-local}
|
|
67
|
+
DB_HOST: cicore_postgres
|
|
68
|
+
DB_PORT: "5432"
|
|
69
|
+
DB_NAME: ${DB_NAME:-cicore_db}
|
|
70
|
+
DB_USER: ${DB_USER:-cicore}
|
|
71
|
+
DB_PASS: ${DB_PASS}
|
|
72
|
+
CONTROL_PLANE_DSN: ${CONTROL_PLANE_DSN:-}
|
|
73
|
+
REDIS_HOST: cicore_redis
|
|
74
|
+
REDIS_PORT: "6379"
|
|
75
|
+
REDIS_PASSWORD: ${REDIS_PASSWORD}
|
|
76
|
+
REDIS_DB_CACHE: "1"
|
|
77
|
+
REDIS_DB_QUEUE: "2"
|
|
78
|
+
REDIS_DB_PUBSUB: "3"
|
|
79
|
+
JWT_SECRET: ${JWT_SECRET}
|
|
80
|
+
NUXT_PUBLIC_API_BASE: ${NUXT_PUBLIC_API_BASE:-}
|
|
81
|
+
CICORE_PAYMENT_GATEWAY: ${CICORE_PAYMENT_GATEWAY:-mock}
|
|
82
|
+
CICORE_PAYMENT_WEBHOOK_SECRET: ${CICORE_PAYMENT_WEBHOOK_SECRET:-}
|
|
83
|
+
KASA_BASE_URL: ${KASA_BASE_URL:-}
|
|
84
|
+
KASA_SERVICE_TOKEN: ${KASA_SERVICE_TOKEN:-}
|
|
85
|
+
KASA_SSH_AUTHORITY: ${KASA_SSH_AUTHORITY:-false}
|
|
86
|
+
KASA_LICENSE_AUTHORITY: ${KASA_LICENSE_AUTHORITY:-false}
|
|
87
|
+
DEPLOYMENT_MOCK: ${DEPLOYMENT_MOCK:-false}
|
|
88
|
+
TZ: ${TIMEZONE:-Europe/Istanbul}
|
|
89
|
+
volumes:
|
|
90
|
+
- ./logs/php:/var/www/storage/logs
|
|
91
|
+
- ./uploads:/var/www/uploads
|
|
92
|
+
- ./addons:/var/www/addons
|
|
93
|
+
depends_on:
|
|
94
|
+
cicore_postgres:
|
|
95
|
+
condition: service_healthy
|
|
96
|
+
cicore_redis:
|
|
97
|
+
condition: service_healthy
|
|
98
|
+
healthcheck:
|
|
99
|
+
test: ["CMD-SHELL", "php-fpm-healthcheck || exit 1"]
|
|
100
|
+
interval: 15s
|
|
101
|
+
timeout: 5s
|
|
102
|
+
retries: 5
|
|
103
|
+
start_period: 30s
|
|
104
|
+
networks:
|
|
105
|
+
- cicore_internal
|
|
106
|
+
|
|
107
|
+
cicore_nuxt:
|
|
108
|
+
image: ${CICORE_REGISTRY:-cisofttr}/cicore-nuxt:${CICORE_IMAGE_TAG:-b11}
|
|
109
|
+
container_name: cicore_nuxt
|
|
110
|
+
restart: unless-stopped
|
|
111
|
+
environment:
|
|
112
|
+
NUXT_PUBLIC_API_BASE: ${NUXT_PUBLIC_API_BASE:-}
|
|
113
|
+
NUXT_PUBLIC_WS_URL: ${NUXT_PUBLIC_WS_URL:-}
|
|
114
|
+
NUXT_PUBLIC_HOST: ${NUXT_PUBLIC_HOST:-}
|
|
115
|
+
NUXT_API_BASE_SERVER: http://cicore_nginx
|
|
116
|
+
TZ: ${TIMEZONE:-Europe/Istanbul}
|
|
117
|
+
depends_on:
|
|
118
|
+
- cicore_php
|
|
119
|
+
networks:
|
|
120
|
+
- cicore_internal
|
|
121
|
+
|
|
122
|
+
cicore_nginx:
|
|
123
|
+
image: ${CICORE_REGISTRY:-cisofttr}/cicore-nginx:${CICORE_IMAGE_TAG:-b11}
|
|
124
|
+
container_name: cicore_nginx
|
|
125
|
+
restart: unless-stopped
|
|
126
|
+
ports:
|
|
127
|
+
- "${HTTP_PORT:-80}:80"
|
|
128
|
+
- "${HTTPS_PORT:-443}:443"
|
|
129
|
+
depends_on:
|
|
130
|
+
cicore_php:
|
|
131
|
+
condition: service_healthy
|
|
132
|
+
cicore_nuxt:
|
|
133
|
+
condition: service_started
|
|
134
|
+
healthcheck:
|
|
135
|
+
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1/health || exit 1"]
|
|
136
|
+
interval: 30s
|
|
137
|
+
timeout: 5s
|
|
138
|
+
retries: 3
|
|
139
|
+
start_period: 20s
|
|
140
|
+
networks:
|
|
141
|
+
- cicore_internal
|
|
142
|
+
|
|
143
|
+
networks:
|
|
144
|
+
cicore_internal:
|
|
145
|
+
driver: bridge
|