@package-broker/dist 2.0.0-rc.3 → 2.0.0-rc.4

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.
Files changed (59) hide show
  1. package/README.md +8 -0
  2. package/node/assets/access.62e9484517a0.js +1 -0
  3. package/node/assets/app.45b156168495.css +2 -0
  4. package/node/assets/{app.e8434f3343de.js → app.c064670cdc0d.js} +5 -5
  5. package/node/assets/audit.b7c40b9dc998.js +1 -0
  6. package/node/assets/{chunk.3704953b4a66.js → chunk.28a4d8aab337.js} +1 -1
  7. package/node/assets/chunk.3fcd6998795a.js +1 -0
  8. package/node/assets/chunk.51497edc7697.js +4 -0
  9. package/node/assets/chunk.56d473a1587d.js +1 -0
  10. package/node/assets/chunk.675b635d9462.js +1 -0
  11. package/node/assets/{chunk.bb25fc845269.js → chunk.6ea6bdcaa465.js} +1 -1
  12. package/node/assets/{chunk.f922af39a279.js → chunk.741aec8d1ff9.js} +1 -1
  13. package/node/assets/chunk.815f9a91c741.js +1 -0
  14. package/node/assets/chunk.8442124f6802.js +1 -0
  15. package/node/assets/{chunk.862544cf5835.js → chunk.965b76812604.js} +1 -1
  16. package/node/assets/{chunk.bf48b04e6a00.js → chunk.a6d755a9789f.js} +1 -1
  17. package/node/assets/chunk.d18497920e4d.js +1 -0
  18. package/node/assets/{chunk.ce96495b8b55.js → chunk.d813fefb410d.js} +1 -1
  19. package/node/assets/chunk.e3b0c44298fc.js +0 -0
  20. package/node/assets/{chunk.7cb6f6b4daaa.js → chunk.f54ea1378c8c.js} +1 -1
  21. package/node/assets/chunk.fd375c54b526.js +1 -0
  22. package/node/assets/import.e7a1e5834631.js +1 -0
  23. package/node/assets/index.html +9 -6
  24. package/node/assets/manifest.json +66 -38
  25. package/node/assets/notifications.19225fe12044.js +1 -0
  26. package/node/assets/npm-login.e059678af13d.js +1 -0
  27. package/node/assets/packages.ab5ab25b1c75.js +2 -0
  28. package/node/assets/projects.927fe18c785c.js +1 -0
  29. package/node/assets/setup.8e977608d413.js +1 -0
  30. package/node/assets/setup.html +2 -2
  31. package/node/assets/sources.ae50f239f80f.js +1 -0
  32. package/node/assets/tokens.6b86d8d97e07.js +4 -0
  33. package/node/assets.json +2 -2
  34. package/node/build-info.json +4 -4
  35. package/node/generated/manifest.json +53 -2
  36. package/node/migrations/core/0002_npm_publish.sql +88 -0
  37. package/node/migrations/core/0003_npm_identity.sql +96 -0
  38. package/node/migrations/core/0004_source_revision.sql +1 -0
  39. package/node/migrations/core/0005_package_settings_revision.sql +1 -0
  40. package/node/migrations/core/0006_npm_login_handoff.sql +39 -0
  41. package/node/migrations/core/0007_npm_vcs_build_outcomes.sql +10 -0
  42. package/node/migrations/core/0008_registry_policy.sql +49 -0
  43. package/node/migrations/core/0009_npm_notifications.sql +108 -0
  44. package/node/server.js +62532 -42978
  45. package/package.json +1 -1
  46. package/prebuilt.json +47 -32
  47. package/node/assets/access.6859f43998ca.js +0 -1
  48. package/node/assets/app.f15f8f21f88b.css +0 -2
  49. package/node/assets/audit.576009342714.js +0 -1
  50. package/node/assets/chunk.297a2d571f9c.js +0 -4
  51. package/node/assets/chunk.6e23a75a1324.js +0 -1
  52. package/node/assets/chunk.855a50f45830.js +0 -1
  53. package/node/assets/chunk.976a2ff4338e.js +0 -1
  54. package/node/assets/import.e2a1e35fcb8d.js +0 -1
  55. package/node/assets/packages.a8726e5144de.js +0 -1
  56. package/node/assets/projects.711deb86b7c9.js +0 -1
  57. package/node/assets/setup.dfed30ecfbad.js +0 -1
  58. package/node/assets/sources.d0ba0048bd96.js +0 -1
  59. package/node/assets/tokens.f48d235e8d25.js +0 -4
@@ -0,0 +1,88 @@
1
+ -- pb:phase expand
2
+
3
+ ALTER TABLE source ADD COLUMN require_publish_approval INTEGER NOT NULL DEFAULT 0 CONSTRAINT source_publish_approval CHECK (require_publish_approval IN (0, 1));
4
+ ALTER TABLE package ADD COLUMN new_project_access_mode TEXT NOT NULL DEFAULT 'none' CONSTRAINT package_access_mode CHECK (new_project_access_mode IN ('none', 'request'));
5
+ ALTER TABLE package ADD COLUMN held_until_active INTEGER NOT NULL DEFAULT 0 CONSTRAINT package_held CHECK (held_until_active IN (0, 1));
6
+
7
+ CREATE UNIQUE INDEX user_account_org_id ON user_account (id, org_id);
8
+
9
+ CREATE TABLE publish_approval (
10
+ id TEXT NOT NULL PRIMARY KEY,
11
+ org_id TEXT NOT NULL REFERENCES organization (id),
12
+ package_id TEXT NOT NULL,
13
+ version_id TEXT NOT NULL UNIQUE,
14
+ source_id TEXT NOT NULL,
15
+ hold_approval INTEGER NOT NULL CONSTRAINT publish_hold_approval CHECK (hold_approval IN (0, 1)),
16
+ hold_scan INTEGER NOT NULL CONSTRAINT publish_hold_scan CHECK (hold_scan IN (0, 1)),
17
+ approval_state TEXT NOT NULL CONSTRAINT publish_approval_state CHECK (approval_state IN ('not_required', 'pending', 'approved', 'rejected', 'expired')),
18
+ scan_state TEXT NOT NULL CONSTRAINT publish_scan_state CHECK (scan_state IN ('not_required', 'queued', 'running', 'allowed', 'denied', 'failed')),
19
+ required_scanners_json TEXT NOT NULL DEFAULT '[]' CONSTRAINT publish_scanners_json CHECK (json_valid(required_scanners_json)),
20
+ scan_attempts INTEGER NOT NULL DEFAULT 0 CONSTRAINT publish_attempts CHECK (scan_attempts >= 0),
21
+ requested_by_type TEXT NOT NULL CONSTRAINT publish_requester_type CHECK (requested_by_type IN ('user', 'service')),
22
+ requested_by_id TEXT NOT NULL,
23
+ token_id TEXT NOT NULL,
24
+ route_project_id TEXT,
25
+ dist_tags_json TEXT NOT NULL DEFAULT '{}' CONSTRAINT publish_tags_json CHECK (json_valid(dist_tags_json)),
26
+ readme_pending INTEGER NOT NULL DEFAULT 0 CONSTRAINT publish_readme_pending CHECK (readme_pending IN (0, 1)),
27
+ decided_by_user_id TEXT,
28
+ decided_at TEXT,
29
+ decision_reason TEXT CONSTRAINT publish_reason_bytes CHECK (decision_reason IS NULL OR length(CAST(decision_reason AS BLOB)) <= 1000),
30
+ scan_verdict_json TEXT NOT NULL DEFAULT '[]' CONSTRAINT publish_verdict_json CHECK (json_valid(scan_verdict_json)),
31
+ expires_at TEXT NOT NULL,
32
+ revision INTEGER NOT NULL DEFAULT 1 CONSTRAINT publish_revision CHECK (revision >= 1),
33
+ created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
34
+ updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
35
+ CONSTRAINT publish_approval_hold CHECK ((hold_approval = 0) = (approval_state = 'not_required')),
36
+ CONSTRAINT publish_scan_hold CHECK ((hold_scan = 0) = (scan_state = 'not_required')),
37
+ CONSTRAINT publish_decision_time CHECK ((decided_at IS NOT NULL) = (approval_state IN ('approved', 'rejected', 'expired'))),
38
+ CONSTRAINT publish_decision_actor CHECK (approval_state NOT IN ('approved', 'rejected') OR decided_by_user_id IS NOT NULL),
39
+ CONSTRAINT publish_expiry_actor CHECK (approval_state <> 'expired' OR decided_by_user_id IS NULL),
40
+ FOREIGN KEY (org_id, package_id) REFERENCES package (org_id, id),
41
+ FOREIGN KEY (org_id, version_id) REFERENCES version (org_id, id),
42
+ FOREIGN KEY (org_id, source_id) REFERENCES source (org_id, id),
43
+ FOREIGN KEY (org_id, route_project_id) REFERENCES project (org_id, id),
44
+ FOREIGN KEY (org_id, decided_by_user_id) REFERENCES user_account (org_id, id)
45
+ ) STRICT;
46
+
47
+ CREATE INDEX publish_approval_package ON publish_approval (org_id, package_id);
48
+ CREATE INDEX publish_approval_list ON publish_approval (org_id, approval_state, id);
49
+ CREATE INDEX publish_approval_expiry ON publish_approval (org_id, expires_at, id) WHERE approval_state = 'pending';
50
+ CREATE INDEX publish_approval_scan ON publish_approval (org_id, scan_state, updated_at, id);
51
+
52
+ CREATE TABLE package_access_request (
53
+ id TEXT NOT NULL PRIMARY KEY,
54
+ org_id TEXT NOT NULL REFERENCES organization (id),
55
+ package_id TEXT NOT NULL,
56
+ project_id TEXT NOT NULL,
57
+ state TEXT NOT NULL DEFAULT 'pending' CONSTRAINT access_state CHECK (state IN ('pending', 'approved', 'rejected', 'expired')),
58
+ requested_by_user_id TEXT NOT NULL,
59
+ reason TEXT CONSTRAINT access_reason_bytes CHECK (reason IS NULL OR length(CAST(reason AS BLOB)) <= 1000) CONSTRAINT access_reason_controls CHECK (reason IS NULL OR (instr(reason, char(0)) = 0 AND glob(char(42,91,1,2,3,4,5,6,7,8,11,12,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127,93,42), reason) = 0)),
60
+ decided_by_user_id TEXT,
61
+ decided_at TEXT,
62
+ decision_reason TEXT CONSTRAINT access_decision_reason_bytes CHECK (decision_reason IS NULL OR length(CAST(decision_reason AS BLOB)) <= 1000) CONSTRAINT access_decision_reason_controls CHECK (decision_reason IS NULL OR (instr(decision_reason, char(0)) = 0 AND glob(char(42,91,1,2,3,4,5,6,7,8,11,12,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127,93,42), decision_reason) = 0)),
63
+ expires_at TEXT NOT NULL,
64
+ revision INTEGER NOT NULL DEFAULT 1 CONSTRAINT access_revision CHECK (revision >= 1),
65
+ created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
66
+ updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
67
+ FOREIGN KEY (org_id, package_id) REFERENCES package (org_id, id),
68
+ FOREIGN KEY (org_id, project_id) REFERENCES project (org_id, id),
69
+ CONSTRAINT access_decision_actor CHECK (state NOT IN ('approved', 'rejected') OR decided_by_user_id IS NOT NULL),
70
+ CONSTRAINT access_expiry_actor CHECK (state <> 'expired' OR decided_by_user_id IS NULL),
71
+ CONSTRAINT access_decision_time CHECK ((decided_at IS NOT NULL) = (state IN ('approved', 'rejected', 'expired'))),
72
+ FOREIGN KEY (org_id, requested_by_user_id) REFERENCES user_account (org_id, id),
73
+ FOREIGN KEY (org_id, decided_by_user_id) REFERENCES user_account (org_id, id)
74
+ ) STRICT;
75
+
76
+ CREATE UNIQUE INDEX package_access_request_pending ON package_access_request (package_id, project_id) WHERE state = 'pending';
77
+ CREATE INDEX package_access_request_list ON package_access_request (org_id, state, id);
78
+ CREATE INDEX package_access_request_expiry ON package_access_request (org_id, expires_at, id) WHERE state = 'pending';
79
+
80
+ CREATE TABLE version_readme (
81
+ version_id TEXT NOT NULL PRIMARY KEY,
82
+ org_id TEXT NOT NULL REFERENCES organization (id),
83
+ filename TEXT NOT NULL,
84
+ body TEXT NOT NULL CONSTRAINT readme_body_bytes CHECK (length(CAST(body AS BLOB)) <= 524288),
85
+ created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
86
+ CONSTRAINT readme_controls CHECK (instr(body, char(0)) = 0 AND glob(char(42,91,1,2,3,4,5,6,7,8,11,12,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127,93,42), body) = 0),
87
+ FOREIGN KEY (org_id, version_id) REFERENCES version (org_id, id) ON DELETE CASCADE
88
+ ) STRICT;
@@ -0,0 +1,96 @@
1
+ -- pb:phase expand
2
+
3
+ CREATE TABLE trusted_publisher (
4
+ id TEXT NOT NULL PRIMARY KEY,
5
+ org_id TEXT NOT NULL REFERENCES organization (id),
6
+ package_name TEXT NOT NULL CONSTRAINT package_name_bytes CHECK (package_name IS NULL OR length(CAST(package_name AS BLOB)) <= 214) CONSTRAINT package_name_controls CHECK (package_name IS NULL OR (instr(package_name, char(0)) = 0 AND glob(char(42,91,1,2,3,4,5,6,7,8,11,12,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127,93,42), package_name) = 0)),
7
+ repository_id TEXT NOT NULL CONSTRAINT repository_id_digits CHECK (length(repository_id) > 0 AND instr(repository_id, char(0)) = 0 AND repository_id NOT GLOB '*[^0-9]*'),
8
+ repository_owner_id TEXT NOT NULL CONSTRAINT repository_owner_id_digits CHECK (length(repository_owner_id) > 0 AND instr(repository_owner_id, char(0)) = 0 AND repository_owner_id NOT GLOB '*[^0-9]*'),
9
+ repository TEXT NOT NULL CONSTRAINT repository_bytes CHECK (repository IS NULL OR length(CAST(repository AS BLOB)) <= 140) CONSTRAINT repository_controls CHECK (repository IS NULL OR (instr(repository, char(0)) = 0 AND glob(char(42,91,1,2,3,4,5,6,7,8,11,12,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127,93,42), repository) = 0)),
10
+ workflow TEXT NOT NULL CONSTRAINT workflow_bytes CHECK (workflow IS NULL OR length(CAST(workflow AS BLOB)) <= 255) CONSTRAINT workflow_controls CHECK (workflow IS NULL OR (instr(workflow, char(0)) = 0 AND glob(char(42,91,1,2,3,4,5,6,7,8,11,12,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127,93,42), workflow) = 0)),
11
+ environment TEXT NOT NULL DEFAULT '' CONSTRAINT environment_bytes CHECK (environment IS NULL OR length(CAST(environment AS BLOB)) <= 255) CONSTRAINT environment_controls CHECK (environment IS NULL OR (instr(environment, char(0)) = 0 AND glob(char(42,91,1,2,3,4,5,6,7,8,11,12,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127,93,42), environment) = 0)),
12
+ ref_pattern TEXT CONSTRAINT ref_pattern_bytes CHECK (ref_pattern IS NULL OR length(CAST(ref_pattern AS BLOB)) <= 255) CONSTRAINT ref_pattern_controls CHECK (ref_pattern IS NULL OR (instr(ref_pattern, char(0)) = 0 AND glob(char(42,91,1,2,3,4,5,6,7,8,11,12,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127,93,42), ref_pattern) = 0)),
13
+ service_principal_id TEXT NOT NULL,
14
+ created_by_user_id TEXT NOT NULL,
15
+ created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
16
+ disabled_at TEXT,
17
+ last_used_at TEXT,
18
+ revision INTEGER NOT NULL DEFAULT 1 CONSTRAINT publisher_revision CHECK (revision >= 1),
19
+ FOREIGN KEY (org_id, service_principal_id) REFERENCES service_principal (org_id, id),
20
+ FOREIGN KEY (org_id, created_by_user_id) REFERENCES user_account (org_id, id)
21
+ ) STRICT;
22
+
23
+ CREATE UNIQUE INDEX trusted_publisher_org_id ON trusted_publisher (org_id, id);
24
+ CREATE UNIQUE INDEX trusted_publisher_binding ON trusted_publisher (org_id, package_name, repository_id, workflow, environment);
25
+
26
+ ALTER TABLE token ADD COLUMN trusted_publisher_id TEXT REFERENCES trusted_publisher (id) ON DELETE SET NULL;
27
+ ALTER TABLE token ADD COLUMN package_name TEXT CONSTRAINT package_name_bytes CHECK (package_name IS NULL OR length(CAST(package_name AS BLOB)) <= 214) CONSTRAINT package_name_controls CHECK (package_name IS NULL OR (instr(package_name, char(0)) = 0 AND glob(char(42,91,1,2,3,4,5,6,7,8,11,12,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127,93,42), package_name) = 0));
28
+ CREATE UNIQUE INDEX token_org_id ON token (id, org_id);
29
+ CREATE INDEX token_trusted_publisher ON token (org_id, trusted_publisher_id) WHERE trusted_publisher_id IS NOT NULL;
30
+
31
+ -- ADD COLUMN cannot add a composite foreign key to the existing token table.
32
+ CREATE TRIGGER token_trusted_publisher_insert BEFORE INSERT ON token
33
+ WHEN NEW.trusted_publisher_id IS NOT NULL AND NOT EXISTS (
34
+ SELECT 1 FROM trusted_publisher WHERE org_id = NEW.org_id AND id = NEW.trusted_publisher_id
35
+ )
36
+ BEGIN
37
+ SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed');
38
+ END;
39
+
40
+ CREATE TRIGGER token_trusted_publisher_update BEFORE UPDATE OF org_id, trusted_publisher_id ON token
41
+ WHEN NEW.trusted_publisher_id IS NOT NULL AND NOT EXISTS (
42
+ SELECT 1 FROM trusted_publisher WHERE org_id = NEW.org_id AND id = NEW.trusted_publisher_id
43
+ )
44
+ BEGIN
45
+ SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed');
46
+ END;
47
+
48
+ CREATE TRIGGER trusted_publisher_token_org_update BEFORE UPDATE OF org_id ON trusted_publisher
49
+ WHEN EXISTS (
50
+ SELECT 1 FROM token WHERE trusted_publisher_id = OLD.id AND org_id <> NEW.org_id
51
+ )
52
+ BEGIN
53
+ SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed');
54
+ END;
55
+
56
+ CREATE TABLE npm_login_session (
57
+ id TEXT NOT NULL PRIMARY KEY,
58
+ selector_hash TEXT NOT NULL UNIQUE CONSTRAINT selector_hash_hex CHECK (length(CAST(selector_hash AS BLOB)) = 64 AND instr(selector_hash, char(0)) = 0 AND selector_hash NOT GLOB '*[^0-9a-f]*'),
59
+ done_hash TEXT NOT NULL UNIQUE CONSTRAINT done_hash_hex CHECK (length(CAST(done_hash AS BLOB)) = 64 AND instr(done_hash, char(0)) = 0 AND done_hash NOT GLOB '*[^0-9a-f]*'),
60
+ org_id TEXT NOT NULL REFERENCES organization (id),
61
+ project_id TEXT NOT NULL,
62
+ state TEXT NOT NULL DEFAULT 'pending' CONSTRAINT login_state CHECK (state IN ('pending', 'approved', 'consumed')),
63
+ cli_hostname TEXT CONSTRAINT cli_hostname_bytes CHECK (cli_hostname IS NULL OR length(CAST(cli_hostname AS BLOB)) <= 253) CONSTRAINT cli_hostname_controls CHECK (cli_hostname IS NULL OR (instr(cli_hostname, char(0)) = 0 AND glob(char(42,91,1,2,3,4,5,6,7,8,11,12,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127,93,42), cli_hostname) = 0)),
64
+ source_ip TEXT CONSTRAINT source_ip_bytes CHECK (source_ip IS NULL OR length(CAST(source_ip AS BLOB)) <= 45) CONSTRAINT source_ip_controls CHECK (source_ip IS NULL OR (instr(source_ip, char(0)) = 0 AND glob(char(42,91,1,2,3,4,5,6,7,8,11,12,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127,93,42), source_ip) = 0)),
65
+ created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
66
+ expires_at TEXT NOT NULL,
67
+ user_id TEXT,
68
+ token_id TEXT,
69
+ token_ciphertext TEXT,
70
+ token_nonce TEXT,
71
+ token_key_version INTEGER,
72
+ consumed_at TEXT,
73
+ CONSTRAINT login_sealed_token CHECK ((token_ciphertext IS NULL AND token_nonce IS NULL AND token_key_version IS NULL) OR (token_ciphertext IS NOT NULL AND token_nonce IS NOT NULL AND token_key_version IS NOT NULL)),
74
+ CONSTRAINT login_consumed_time CHECK ((state = 'consumed') = (consumed_at IS NOT NULL)),
75
+ CONSTRAINT login_consumed_token CHECK (state <> 'consumed' OR token_ciphertext IS NULL),
76
+ CONSTRAINT login_approved CHECK (state <> 'approved' OR (user_id IS NOT NULL AND token_id IS NOT NULL AND token_ciphertext IS NOT NULL)),
77
+ CONSTRAINT login_pending CHECK (state <> 'pending' OR (user_id IS NULL AND token_id IS NULL AND token_ciphertext IS NULL)),
78
+ FOREIGN KEY (org_id, project_id) REFERENCES project (org_id, id),
79
+ FOREIGN KEY (org_id, user_id) REFERENCES user_account (org_id, id),
80
+ FOREIGN KEY (org_id, token_id) REFERENCES token (org_id, id)
81
+ ) STRICT;
82
+
83
+ CREATE INDEX npm_login_session_pending ON npm_login_session (org_id, project_id, expires_at) WHERE state = 'pending';
84
+ CREATE INDEX npm_login_session_expiry ON npm_login_session (org_id, expires_at);
85
+
86
+ CREATE TABLE oidc_replay (
87
+ issuer TEXT NOT NULL,
88
+ jti TEXT NOT NULL,
89
+ org_id TEXT NOT NULL REFERENCES organization (id),
90
+ trusted_publisher_id TEXT NOT NULL,
91
+ expires_at TEXT NOT NULL,
92
+ PRIMARY KEY (issuer, jti),
93
+ FOREIGN KEY (org_id, trusted_publisher_id) REFERENCES trusted_publisher (org_id, id) ON DELETE CASCADE
94
+ ) STRICT, WITHOUT ROWID;
95
+
96
+ CREATE INDEX oidc_replay_expiry ON oidc_replay (org_id, expires_at);
@@ -0,0 +1 @@
1
+ ALTER TABLE source ADD COLUMN revision INTEGER NOT NULL DEFAULT 1 CHECK (revision >= 1);
@@ -0,0 +1 @@
1
+ ALTER TABLE package ADD COLUMN settings_revision INTEGER NOT NULL DEFAULT 1 CHECK (settings_revision > 0);
@@ -0,0 +1,39 @@
1
+ -- pb:phase contract
2
+
3
+ CREATE TABLE npm_login_session_handoff (
4
+ id TEXT NOT NULL PRIMARY KEY,
5
+ selector_hash TEXT NOT NULL UNIQUE CONSTRAINT selector_hash_hex CHECK (length(CAST(selector_hash AS BLOB)) = 64 AND instr(selector_hash, char(0)) = 0 AND selector_hash NOT GLOB '*[^0-9a-f]*'),
6
+ done_hash TEXT NOT NULL UNIQUE CONSTRAINT done_hash_hex CHECK (length(CAST(done_hash AS BLOB)) = 64 AND instr(done_hash, char(0)) = 0 AND done_hash NOT GLOB '*[^0-9a-f]*'),
7
+ org_id TEXT NOT NULL REFERENCES organization (id),
8
+ project_id TEXT NOT NULL,
9
+ state TEXT NOT NULL DEFAULT 'pending' CONSTRAINT login_state CHECK (state IN ('pending', 'approved', 'delivering', 'consumed')),
10
+ cli_hostname TEXT CONSTRAINT cli_hostname_bytes CHECK (cli_hostname IS NULL OR length(CAST(cli_hostname AS BLOB)) <= 253) CONSTRAINT cli_hostname_controls CHECK (cli_hostname IS NULL OR (instr(cli_hostname, char(0)) = 0 AND glob(char(42,91,1,2,3,4,5,6,7,8,11,12,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127,93,42), cli_hostname) = 0)),
11
+ source_ip TEXT CONSTRAINT source_ip_bytes CHECK (source_ip IS NULL OR length(CAST(source_ip AS BLOB)) <= 45) CONSTRAINT source_ip_controls CHECK (source_ip IS NULL OR (instr(source_ip, char(0)) = 0 AND glob(char(42,91,1,2,3,4,5,6,7,8,11,12,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,127,93,42), source_ip) = 0)),
12
+ created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
13
+ expires_at TEXT NOT NULL,
14
+ user_id TEXT,
15
+ token_id TEXT,
16
+ token_ciphertext TEXT,
17
+ token_nonce TEXT,
18
+ token_key_version INTEGER,
19
+ consumed_at TEXT,
20
+ delivering_at TEXT,
21
+ CONSTRAINT login_delivering CHECK ((state = 'delivering') = (delivering_at IS NOT NULL)),
22
+ CONSTRAINT login_delivery_token CHECK (state <> 'delivering' OR (user_id IS NOT NULL AND token_id IS NOT NULL AND token_ciphertext IS NULL)),
23
+ CONSTRAINT login_sealed_token CHECK ((token_ciphertext IS NULL AND token_nonce IS NULL AND token_key_version IS NULL) OR (token_ciphertext IS NOT NULL AND token_nonce IS NOT NULL AND token_key_version IS NOT NULL)),
24
+ CONSTRAINT login_consumed_time CHECK ((state = 'consumed') = (consumed_at IS NOT NULL)),
25
+ CONSTRAINT login_consumed_token CHECK (state <> 'consumed' OR token_ciphertext IS NULL),
26
+ CONSTRAINT login_approved CHECK (state <> 'approved' OR (user_id IS NOT NULL AND token_id IS NOT NULL AND token_ciphertext IS NOT NULL)),
27
+ CONSTRAINT login_pending CHECK (state <> 'pending' OR (user_id IS NULL AND token_id IS NULL AND token_ciphertext IS NULL)),
28
+ FOREIGN KEY (org_id, project_id) REFERENCES project (org_id, id),
29
+ FOREIGN KEY (org_id, user_id) REFERENCES user_account (org_id, id),
30
+ FOREIGN KEY (org_id, token_id) REFERENCES token (org_id, id)
31
+ ) STRICT;
32
+
33
+ INSERT INTO npm_login_session_handoff (id, selector_hash, done_hash, org_id, project_id, state, cli_hostname, source_ip, created_at, expires_at, user_id, token_id, token_ciphertext, token_nonce, token_key_version, consumed_at)
34
+ SELECT id, selector_hash, done_hash, org_id, project_id, state, cli_hostname, source_ip, created_at, expires_at, user_id, token_id, token_ciphertext, token_nonce, token_key_version, consumed_at FROM npm_login_session;
35
+ DROP TABLE npm_login_session;
36
+ ALTER TABLE npm_login_session_handoff RENAME TO npm_login_session;
37
+ CREATE INDEX npm_login_session_pending ON npm_login_session (org_id, project_id, expires_at) WHERE state = 'pending';
38
+ CREATE INDEX npm_login_session_expiry ON npm_login_session (org_id, expires_at);
39
+ CREATE INDEX npm_login_session_delivery ON npm_login_session (org_id, delivering_at) WHERE state = 'delivering';
@@ -0,0 +1,10 @@
1
+ CREATE TABLE npm_vcs_build_outcome (
2
+ org_id TEXT NOT NULL REFERENCES organization(id) ON DELETE CASCADE,
3
+ version_id TEXT NOT NULL,
4
+ source_ref TEXT NOT NULL CHECK(length(source_ref) = 40),
5
+ packing_policy TEXT NOT NULL,
6
+ retry_generation INTEGER NOT NULL DEFAULT 0 CHECK(retry_generation >= 0),
7
+ outcome TEXT CHECK(outcome IN ('too_large', 'unsupported_files_pattern', 'invalid_packlist', 'invalid_tarball', 'archive_changed', 'internal')),
8
+ PRIMARY KEY (org_id, version_id, source_ref, packing_policy),
9
+ FOREIGN KEY (version_id, org_id) REFERENCES version(id, org_id) ON DELETE CASCADE
10
+ ) STRICT;
@@ -0,0 +1,49 @@
1
+ -- pb:phase expand
2
+
3
+ CREATE TABLE registry_policy_rule (
4
+ id TEXT NOT NULL PRIMARY KEY,
5
+ org_id TEXT NOT NULL REFERENCES organization (id),
6
+ project_id TEXT,
7
+ ecosystem TEXT NOT NULL CHECK (ecosystem IN ('npm', 'composer')),
8
+ package_key TEXT,
9
+ kind TEXT NOT NULL CHECK (kind IN ('min_age', 'block', 'allowlist', 'quarantine', 'client_floor')),
10
+ min_age_seconds INTEGER CHECK (min_age_seconds BETWEEN 0 AND 315360000),
11
+ client_family TEXT CHECK (client_family IN ('npm', 'pnpm', 'yarn', 'composer')),
12
+ client_min_version TEXT,
13
+ deny_unknown INTEGER NOT NULL DEFAULT 0 CHECK (deny_unknown IN (0, 1)),
14
+ reason_code TEXT NOT NULL CHECK (reason_code IN ('malware', 'security_review', 'compatibility', 'organization_policy')),
15
+ incident_id TEXT,
16
+ expires_at TEXT CHECK (expires_at IS NULL OR (length(expires_at) = 24 AND strftime('%Y-%m-%dT%H:%M:%fZ', expires_at) IS expires_at)),
17
+ expiry_audited_at TEXT CHECK (expiry_audited_at IS NULL OR (length(expiry_audited_at) = 24 AND strftime('%Y-%m-%dT%H:%M:%fZ', expiry_audited_at) IS expiry_audited_at)),
18
+ disabled_at TEXT CHECK (disabled_at IS NULL OR (length(disabled_at) = 24 AND strftime('%Y-%m-%dT%H:%M:%fZ', disabled_at) IS disabled_at)),
19
+ disabled_reason TEXT CHECK (disabled_reason IN ('false_positive', 'emergency_compatibility', 'superseded', 'other')),
20
+ revision INTEGER NOT NULL DEFAULT 1 CHECK (revision >= 1),
21
+ created_at TEXT NOT NULL CHECK (length(created_at) = 24 AND strftime('%Y-%m-%dT%H:%M:%fZ', created_at) IS created_at),
22
+ updated_at TEXT NOT NULL CHECK (length(updated_at) = 24 AND strftime('%Y-%m-%dT%H:%M:%fZ', updated_at) IS updated_at),
23
+ UNIQUE (org_id, id),
24
+ FOREIGN KEY (org_id, project_id) REFERENCES project (org_id, id),
25
+ CHECK ((kind = 'min_age' AND min_age_seconds IS NOT NULL) OR (kind <> 'min_age' AND min_age_seconds IS NULL)),
26
+ CHECK ((kind = 'client_floor' AND client_family IS NOT NULL AND client_min_version IS NOT NULL AND package_key IS NULL) OR (kind <> 'client_floor' AND client_family IS NULL AND client_min_version IS NULL)),
27
+ CHECK (kind = 'client_floor' OR deny_unknown = 0),
28
+ CHECK (kind NOT IN ('block', 'allowlist', 'quarantine') OR package_key IS NOT NULL),
29
+ CHECK (kind <> 'quarantine' OR (project_id IS NULL AND expires_at IS NULL AND reason_code = 'malware')),
30
+ CHECK (client_family IS NULL OR (ecosystem = 'composer' AND client_family = 'composer') OR (ecosystem = 'npm' AND client_family IN ('npm', 'pnpm', 'yarn'))),
31
+ CHECK (expires_at IS NULL OR expires_at > created_at),
32
+ CHECK (updated_at >= created_at),
33
+ CHECK ((disabled_at IS NULL) = (disabled_reason IS NULL)),
34
+ CHECK (disabled_at IS NULL OR disabled_at >= created_at),
35
+ CHECK (package_key IS NULL OR length(CAST(package_key AS BLOB)) BETWEEN 1 AND 512),
36
+ CHECK (client_min_version IS NULL OR length(client_min_version) BETWEEN 5 AND 64),
37
+ CHECK (incident_id IS NULL OR length(incident_id) = 26)
38
+ ) STRICT;
39
+
40
+ CREATE INDEX registry_policy_scope ON registry_policy_rule (org_id, ecosystem, project_id, package_key) WHERE disabled_at IS NULL;
41
+ CREATE INDEX registry_policy_expiry ON registry_policy_rule (org_id, expires_at, id) WHERE expires_at IS NOT NULL AND disabled_at IS NULL;
42
+
43
+ CREATE TABLE registry_policy_version (
44
+ org_id TEXT NOT NULL REFERENCES organization (id),
45
+ rule_id TEXT NOT NULL,
46
+ version_normalized TEXT NOT NULL CHECK (length(CAST(version_normalized AS BLOB)) BETWEEN 1 AND 512),
47
+ PRIMARY KEY (org_id, rule_id, version_normalized),
48
+ FOREIGN KEY (org_id, rule_id) REFERENCES registry_policy_rule (org_id, id)
49
+ ) STRICT, WITHOUT ROWID;
@@ -0,0 +1,108 @@
1
+ -- pb:phase expand
2
+
3
+ CREATE UNIQUE INDEX credential_notification_scope ON credential (org_id, project_id, id);
4
+
5
+ CREATE TABLE notification_endpoint (
6
+ org_id TEXT NOT NULL REFERENCES organization (id),
7
+ project_id TEXT NOT NULL,
8
+ id TEXT NOT NULL,
9
+ name TEXT NOT NULL CONSTRAINT notification_endpoint_name CHECK (length(name) BETWEEN 1 AND 80),
10
+ method TEXT NOT NULL CONSTRAINT notification_endpoint_method CHECK (method IN ('POST', 'PUT')),
11
+ events_json TEXT NOT NULL CONSTRAINT notification_endpoint_events CHECK (json_valid(events_json) AND json_type(events_json) = 'array' AND json_array_length(events_json) >= 1 AND length(events_json) <= 256),
12
+ package_pattern TEXT NOT NULL CONSTRAINT notification_endpoint_pattern CHECK (length(package_pattern) BETWEEN 1 AND 50),
13
+ credential_id TEXT NOT NULL,
14
+ headers_configured INTEGER NOT NULL DEFAULT 0 CONSTRAINT notification_endpoint_headers CHECK (headers_configured IN (0, 1)),
15
+ template_configured INTEGER NOT NULL DEFAULT 0 CONSTRAINT notification_endpoint_template CHECK (template_configured IN (0, 1)),
16
+ revision INTEGER NOT NULL DEFAULT 1 CONSTRAINT notification_endpoint_revision CHECK (revision >= 1),
17
+ state TEXT NOT NULL DEFAULT 'disabled' CONSTRAINT notification_endpoint_state CHECK (state IN ('enabled', 'disabled', 'deleted')),
18
+ disabled_reason TEXT CONSTRAINT notification_endpoint_reason CHECK (disabled_reason IN ('manual', 'configuration_changed', 'failures', 'credentials', 'policy', 'gone')),
19
+ failure_streak INTEGER NOT NULL DEFAULT 0 CONSTRAINT notification_endpoint_streak CHECK (failure_streak >= 0),
20
+ last_op_id TEXT,
21
+ created_at TEXT NOT NULL,
22
+ updated_at TEXT NOT NULL,
23
+ PRIMARY KEY (org_id, id),
24
+ UNIQUE (org_id, project_id, id),
25
+ CONSTRAINT notification_endpoint_enabled CHECK (state <> 'enabled' OR disabled_reason IS NULL),
26
+ FOREIGN KEY (org_id, project_id) REFERENCES project (org_id, id),
27
+ FOREIGN KEY (org_id, project_id, credential_id) REFERENCES credential (org_id, project_id, id)
28
+ ) STRICT;
29
+
30
+ CREATE INDEX notification_endpoint_project ON notification_endpoint (org_id, project_id, state, id);
31
+
32
+ CREATE TABLE notification_event (
33
+ org_id TEXT NOT NULL REFERENCES organization (id),
34
+ project_id TEXT NOT NULL,
35
+ id TEXT NOT NULL,
36
+ operation_id TEXT NOT NULL,
37
+ ordinal INTEGER NOT NULL DEFAULT 0 CONSTRAINT notification_event_ordinal CHECK (ordinal >= 0),
38
+ event_type TEXT NOT NULL CONSTRAINT notification_event_type CHECK (event_type IN ('npm.package.published', 'npm.package.released', 'npm.package.unpublished', 'npm.package.deprecation_changed', 'npm.package.dist_tag_changed')),
39
+ source_id TEXT NOT NULL,
40
+ package_key TEXT NOT NULL CONSTRAINT notification_event_key CHECK (length(CAST(package_key AS BLOB)) BETWEEN 1 AND 512),
41
+ payload_json TEXT NOT NULL CONSTRAINT notification_event_payload CHECK (json_valid(payload_json) AND length(CAST(payload_json AS BLOB)) <= 16384),
42
+ occurred_at TEXT NOT NULL,
43
+ dispatched_at TEXT,
44
+ dispatch_generation INTEGER NOT NULL DEFAULT 1 CONSTRAINT notification_event_generation CHECK (dispatch_generation >= 1),
45
+ PRIMARY KEY (org_id, id),
46
+ UNIQUE (org_id, project_id, id),
47
+ UNIQUE (org_id, operation_id, event_type, ordinal),
48
+ FOREIGN KEY (org_id, project_id) REFERENCES project (org_id, id)
49
+ ) STRICT;
50
+
51
+ CREATE INDEX notification_event_dispatch ON notification_event (org_id, dispatched_at, id);
52
+ CREATE INDEX notification_event_retention ON notification_event (org_id, occurred_at, id);
53
+
54
+ CREATE TABLE notification_delivery (
55
+ org_id TEXT NOT NULL REFERENCES organization (id),
56
+ project_id TEXT NOT NULL,
57
+ id TEXT NOT NULL,
58
+ event_id TEXT NOT NULL,
59
+ endpoint_id TEXT NOT NULL,
60
+ endpoint_revision INTEGER NOT NULL CONSTRAINT notification_delivery_endpoint_revision CHECK (endpoint_revision >= 1),
61
+ configuration_credential_id TEXT NOT NULL,
62
+ body_credential_id TEXT,
63
+ state TEXT NOT NULL DEFAULT 'pending' CONSTRAINT notification_delivery_state CHECK (state IN ('pending', 'sending', 'delivered', 'failed', 'cancelled')),
64
+ attempts INTEGER NOT NULL DEFAULT 0 CONSTRAINT notification_delivery_attempts CHECK (attempts BETWEEN 0 AND 8),
65
+ job_generation INTEGER NOT NULL DEFAULT 1 CONSTRAINT notification_delivery_generation CHECK (job_generation >= 1),
66
+ active_job_id TEXT,
67
+ active_fence INTEGER CONSTRAINT notification_delivery_fence CHECK (active_fence >= 1),
68
+ revision INTEGER NOT NULL DEFAULT 1 CONSTRAINT notification_delivery_revision CHECK (revision >= 1),
69
+ next_attempt_at TEXT NOT NULL,
70
+ expires_at TEXT NOT NULL,
71
+ last_status INTEGER CONSTRAINT notification_delivery_status CHECK (last_status BETWEEN 100 AND 599),
72
+ outcome_code TEXT CONSTRAINT notification_delivery_outcome CHECK (outcome_code IN ('ok', 'network', 'timeout', 'http_retry', 'http_permanent', 'redirect', 'policy', 'credentials', 'template', 'unknown', 'expired', 'attempt_limit', 'disabled', 'superseded', 'project_inactive', 'admission_lost', 'deleted')),
73
+ created_at TEXT NOT NULL,
74
+ finished_at TEXT,
75
+ PRIMARY KEY (org_id, id),
76
+ UNIQUE (org_id, event_id, endpoint_id),
77
+ UNIQUE (org_id, project_id, id),
78
+ FOREIGN KEY (org_id, project_id, event_id) REFERENCES notification_event (org_id, project_id, id),
79
+ FOREIGN KEY (org_id, project_id, endpoint_id) REFERENCES notification_endpoint (org_id, project_id, id),
80
+ FOREIGN KEY (org_id, project_id, configuration_credential_id) REFERENCES credential (org_id, project_id, id),
81
+ FOREIGN KEY (org_id, project_id, body_credential_id) REFERENCES credential (org_id, project_id, id),
82
+ CONSTRAINT notification_delivery_finished CHECK ((state IN ('delivered', 'failed', 'cancelled')) = (finished_at IS NOT NULL)),
83
+ CONSTRAINT notification_delivery_sending CHECK (state <> 'sending' OR (active_job_id IS NOT NULL AND active_fence IS NOT NULL))
84
+ ) STRICT;
85
+
86
+ CREATE INDEX notification_delivery_due ON notification_delivery (org_id, state, next_attempt_at, id);
87
+ CREATE INDEX notification_delivery_history ON notification_delivery (org_id, project_id, endpoint_id, created_at, id);
88
+ CREATE INDEX notification_delivery_retention ON notification_delivery (org_id, finished_at, id);
89
+
90
+ CREATE TABLE notification_attempt (
91
+ org_id TEXT NOT NULL REFERENCES organization (id),
92
+ project_id TEXT NOT NULL,
93
+ delivery_id TEXT NOT NULL,
94
+ attempt INTEGER NOT NULL CONSTRAINT notification_attempt_number CHECK (attempt BETWEEN 1 AND 8),
95
+ job_id TEXT NOT NULL,
96
+ fence INTEGER NOT NULL CONSTRAINT notification_attempt_fence CHECK (fence >= 1),
97
+ outcome TEXT NOT NULL CONSTRAINT notification_attempt_outcome CHECK (outcome IN ('started', 'delivered', 'retry', 'failed', 'unknown')),
98
+ outcome_code TEXT CONSTRAINT notification_attempt_code CHECK (outcome_code IN ('ok', 'network', 'timeout', 'http_retry', 'http_permanent', 'redirect', 'policy', 'credentials', 'template', 'unknown')),
99
+ status INTEGER CONSTRAINT notification_attempt_status CHECK (status BETWEEN 100 AND 599),
100
+ duration_ms INTEGER CONSTRAINT notification_attempt_duration CHECK (duration_ms >= 0),
101
+ started_at TEXT NOT NULL,
102
+ finished_at TEXT,
103
+ PRIMARY KEY (org_id, delivery_id, attempt),
104
+ FOREIGN KEY (org_id, project_id, delivery_id) REFERENCES notification_delivery (org_id, project_id, id) ON DELETE CASCADE,
105
+ CONSTRAINT notification_attempt_finished CHECK ((outcome = 'started') = (finished_at IS NULL))
106
+ ) STRICT;
107
+
108
+ CREATE INDEX notification_attempt_started ON notification_attempt (org_id, outcome, started_at, delivery_id);